Yii2 结构指引

概述

同laravel一样,yii应用也有两个入口,分别是 web 基础应用 和console 控制台应用

  • 入口脚本

    • 定义全局常量
    • 注册 Composer 自动加载器
    • 包含 Yii 类文件
    • 加载应用配置
    • 创建一个应用实例并配置
    • 调用 yii\base\Application::run($config) 来处理请求
  • 应用主体

    • 实例化 (new yii\web\Application($config))->run()
    • 属性
      • 必要属性 id, basePath
      • 重要属性 aliases,bootstrap
        • 可将模块ID加入到 bootstrap 数组中
        • bootsrap 属性中每个组件需要指定以下一项
          • 应用 组件 ID
          • 模块 ID
          • 类名
          • 配置数组
          • 创建并返回一个组件的无名称函数
        • catchAll属性 仅 Web applications 网页应用支持
          • 指定一个要处理所有用户请求的 控制器方法, 通常在维护模式下使用,同一个方法处理所有用户请求

            如果模块 ID 和应用组件 ID 同名,优先使用应用组件 ID 在启动阶段,每个组件都会实例化。如果组件类实现接口 yii\base\BootstrapInterface,也会调用 bootstrap() 方法

  • 应用组件components配置

    • 每一个应用组件指定一个key-value对的数组,key代表组件ID, value代表组件类名或 配置
    • 应用中注册的组件,可以通过表达式 \Yii::$app->ComponentID 全局访问
  • 属性 controllerMap

    • 指定一个控制器 ID 到任意控制器类
    • 数组的键代表控制器ID, 数组的值代表对应的类名
  • 属性controllerNamespace

    • 该属性指定控制器类默认的命名空间,默认为 app\controllers
  • 属性 modules,键为模块id

  • languagename,全局可访问的参数 params

  • sourceLanguage, timeZone 语言,时区

  • 实用属性

    • charset 应用使用的字符集
    • defaultRoute 该属性指定未配置的请求的响应 路由 规则,可能包含模块 ID,控制器 ID,动作 ID
    • extensions 该属性用数组列表指定应用安装和使用的 扩展, 默认使用 @vendor/yiisoft/extensions.php 文件返回的数组
    • layout,layoutPath,runtimePath,viewPath,vendorPath,enableCoreCommands

应用事件

  • 应用在处理请求过程中会触发的事件
    • on eventName 语法配置事件处理代码
  • 事件
    • EVENT_BEFORE_REQUEST
    • EVENT_AFTER_REQUEST
    • EVENT_BEFORE_ACTION
    • EVENT_AFTER_ACTION
  • 流程
    • 应用主体对象触发 beforeAction 事件 --> 模块触发 --> 控制器触发
    • 注意 模块 和 控制器 都会触发 afterAction 事件。 这些对象的触发顺序和 beforeAction 相反

任何一个事件处理中设置 yii\base\ActionEvent::$isValid 设置为 false 会停止触发后面的事件

应用组件

  • 应用主体是服务定位器, 它部署一组提供各种不同功能的 应用组件 来处理请求
  • 访问已注册到应用上的组件实例 \Yii::$app->componentID
  • 应用组件在 应用主体配置 yii\base\Application::$components 属性

应用组件就像全局变量,谨慎注册太多应用组件 一个应用组件只会在第一次访问时实例化, 如果处理请求过程没有访问的话就不实例化

  • 可以使用闭包来引导启动自定义的组件
  • 核心应用组件(类似laravel中的应用启动数组)
    • request 组件 用来收集用户请求并解析 路由
    • db 代表一个可以执行数据库操作的数据库连接
    • assetManager 管理资源包和资源发布
    • errorHandler: 处理 PHP 错误和异常
    • formatter: 格式化输出显示给终端用户的数据
    • i18n: 支持信息翻译和格式化
    • log: 管理日志对象
    • yii\swiftmailer\Mailer 支持生成邮件结构并发送
    • response: 代表发送给用户的响应
    • session: 代表会话信息
    • urlManager: 支持URL地址解析和创建
    • user: 代表认证登录用户信息,仅在Web applications 网页应用中可用
    • view: 支持渲染视图

控制器

  • 继承 yii\base\Controller 类的对象,负责处理请求和生成响应
  • 动作
    • 控制器由 操作 组成,它是执行终端用户请求的最基础的单元, 一个控制器可有一个或多个操作
  • 路由
    • 终端用户通过所谓的路由寻找到动作
    • 模块ID: 仅存在于控制器属于非应用的模块
    • 控制器ID: 同应用(或同模块如果为模块下的控制)
    • 操作ID: 同控制器下唯一标识操作的字符串
  • 创建
    • 控制器应继承yii\web\Controller 或它的子类
    • 继承 yii\console\Controller 或它的子类
    • 控制器ID 应仅包含英文小写字母、数字、下划线、中横杠和正斜杠
  • 控制器布署
    • 通过配置 controller map 来强制上述的控制器ID和类名对应,
    • 应用场景 在使用第三方不能掌控类名的控制器上
  • 创建动作
    • 内联操作 无需重用的情况下优先使用
    • 独立操作 继承 yii\base\Action 或它的子类的类
      • 主要用于多个控制器重用,或重构为扩展
      • 应用场景如 yii\web\ViewAction , yii\web\ErrorAction

要使用独立操作,需要通过控制器中覆盖 yii\base\Controller::actions() 方法在action map中申明 创建的独立操作类,必须实现公有的名称为 run() 的方法,与操作方法类似

  • 动作结果
    • 返回值可为 响应 对象,作为响应发送给终端用户
    • 对于 Web applications 网页应用,返回值可为任意数据, 它赋值给yii\web\Response::$data
    • 对于 console applications 控制台应用,返回值可为整数, 表示命令行下执行的 exit status 退出状态
  • 动作参数,对于Web applications 网页应用, 每个动作参数的值从$_GET中获得,参数名作为键
  • 默认动作
    • 当路由 只包含控制器ID, 会使用所请求的控制器的默认操作
    • 由控制器中的 $defaultAction 指定默认动作
  • 控制器生命周期
    • 应用主体 --> 请求路由 --> 创建控制器
      1. 控制器 init() 方法被调用
      2. 创建操作对象
        • 未提供ID,使用default action ID 默认操作ID
        • 在 action map(控制器actions方法) 找到操作ID, 会创建一个独立操作
        • 操作ID对应操作方法,会创建一个内联操作
        • 否则会抛出 yii\base\InvalidRouteException 异常
      3. 控制器按顺序调用应用主体、模块(如果控制器属于模块)、 控制器的 beforeAction() 方法
        • 任意一个调用返回false,后面未调用的 beforeAction() 会跳过并且操作执行会被取消
        • 默认情况下每个 beforeAction() 方法会触发一个 beforeAction 事件
      4. 控制器执行操作
      5. 控制器按顺序调用控制器、模块(如果控制器属于模块)、应用主体的 afterAction() 方法
      6. 应用主体获取操作结果并赋值给响应
  • 小结
    • 访问请求数据
    • 根据请求数据调用模型方法和其他服务组件
    • 使用视图构造响应
    • 不应处理被模型处理的请求数据
    • 应避免嵌入html或其他代码,这些代码最好在视图中处理

模型类

  • 代表业务数据,规则和逻辑的对象
  • yii\base\Model 类特性
    • 属性
      • 定义 覆盖 attriutes()指定模型所拥有的属性 或定义非静态公有成员变量
      • 实现了ArrayAccess 数组访问, ArrayIterator 数组迭代器
    • 属性标签
      • $model->getAttributeLabel('name')
      • 通过使用模型的 scenario场景, 可对相同的属性返回不同的标签
    • 块赋值
    • 验证规则
    • 数据导出
  • 场景
    • 在不同的场景下, 模型可能会使用不同的业务规则和逻辑
    • 例如 email 属性在注册时强制要求有,但在登陆时不需要
    • 使用 yii\base\Model::$scenario 属性保持使用场景的跟踪
    • 可以通过覆盖 yii\base\Model::scenarios() 方法来自定义行为
    • 场景特性主要在验证 和 属性块赋值 中使用
  • 验证规则
    • 调用 yii\base\Model::validate() 来验证接收到的数据
    • 使用 yii\base\Model::rules() 申明的验证规则
    • 使用 yii\base\Model::$errors 属性保存错误
  • 非安全属性验证
    • 在 scenarios() 方法中属性名加一个惊叹号 !
    • 应用场景 在某些情况下,可能想验证一个属性但不想让他是安全
  • 数据导出
    • 模型转换成数组 yii\base\Model::attributes()
    • 数组转换成需要的格式
      • 通常使用 数据转换器如 yii\web\JsonResponseFormatter
      • 更灵活和强大的将模型转换为数组的方式是使用 yii\base\Model::toArray() 方法
  • 字段
    • 可以通过覆盖 fields() 和/或 extraFields() 方法来改变这种行为
    • fields() 方法定义的字段是默认字段, 表示 toArray() 方法默认会返回这些字段
    • 应用场景 通常使用覆盖 fields() 方法过滤掉 一些包含敏感信息的字段
  • 实践
    • 模型是代表业务数据、规则和逻辑的中心地方,通常在很多地方重用
    • 不应直接访问请求,session和其他环境数据, 这些数据应该由控制器传入到模型
    • 单个模型中避免太多的 场景
      • 常用策略 定义可被多个 应用主体 或 模块 共享的模型基类集合。 这些模型类应包含通用的最小规则集合和逻辑
      • 通过继承对应的模型基类来定义具体的模型类,具体模型类包含应用主体或模块指定的规则和逻辑

视图

  • 视图模板为PHP脚本文件, 主要包含HTML代码和展示类PHP代码,通过view应用组件来管理渲染视图
  • 组织视图
    • 控制器渲染的视图文件默认放在 @app/views/ControllerID 目录下
    • 对于 小部件 渲染的视图文件默认放在 WidgetPath/views 目录
    • 可覆盖控制器或小部件的 yii\base\ViewContextInterface::getViewPath() 方法来自定义视图文件默认目录
  • 控制器中渲染
    • render(): 渲染一个 视图名 并使用一个 布局 返回到渲染结果
    • renderPartial(): 渲染一个 视图名 并且不使用布局
    • renderAjax(): 渲染一个 视图名 并且不使用布局
    • renderFile(): 渲染一个视图文件目录或 别名下的视图文件
  • 小部件中渲染
    • render(): 渲染一个 视图名.
    • renderFile(): 渲染一个视图文件目录或 别名下的视图文件
  • 视图中渲染
    • 调用view component视图组件提供的以下方法
    • render(): 渲染一个 视图名
    • renderAjax(): 渲染一个 视图名 并注入所有注册的JS/CSS脚本和文件
  • 其他地方渲染
    • Yii::$app->view 访问 view 应用组件
  • 视图名规则
    • 可省略文件扩展名
    • 以双斜杠 // 开头,对应的视图文件路径为 @app/views/ViewName
    • 视图名以单斜杠/开始,视图文件路径以当前使用模块 的 view path 开始
  • 视图中访问数据
    • 推送方式 是通过视图渲染方法的第二个参数传递数据,据格式应为名称-值的数组
    • 拉取方式 可让视图从view component视图组件或其他对象中主动获得数据(如Yii::app), app),‘this->context->id
    • view component 视图组件提供 params 参数属性来让不同视图共享数据
    • 布局中访问数据,可使用两个预定义变量 $this 和 $content
      • 前者对应和普通视图类似的view 视图组件 后者包含调用render()方法渲染内容视图的结果
  • 视图事件

模块化

  • 创建模块
    • 存在一个模块类文件,该文件所在目录称之为 base_path
    • 每个模块都有一个继承 yii\base\Module 的模块类,该类可被自动加载
      • 应用主体实例 类似会创建该模块类唯一实例,模块实例用来帮模块内代码共享数据和组件
      • 通常模块块类 init() 方法包含很多初始化模块属性代码
  • 引导启动模块
    • 模块加入到应用主体的 bootstrap 属性中
    • 配置 modules项,值为数组,键为模块名,值模块类
  • 模块嵌套
    • 子模块必须在父模块 modules 属性中申明
    • 模块在大型项目中常备使用,这些项目的特性可分组

过滤器

  • 除了控制器外,可在 模块或应用主体 中申明过滤器

在模块或应用主体中申明过滤器,在only 和 except 属性中使用路由 代替动作 ID, 因在模块或应用主体中只用动作ID并不能唯一指定到具体动作

  • 过滤器是 控制器动作 执行之前或之后执行的对象

  • 应用场景 权限验证,内容压缩过滤器可在动作执行之后发给终端用户之前压缩响应内容

  • 使用

    • 过滤器 本质上是一类特殊的行为,可在控制器的 behaviors() 方法来声明过滤器
    • 控制器类的过滤器默认应用到该类的 所有 动作, only属性则明确指定
  • 多个过滤器执行规则

    • 预过滤
      • 执行应用主体 --> 模块级别 --> 控制器 --> 若过滤器终止后续不再执行
    • 成功通过预过滤器则进入执行动作
    • 后过滤 倒序执行控制器过滤器--> 倒序模块中 --> 倒序执行应用主体中 behaviors() 列出的过滤器
  • 创建过滤器

    • 若返回值为 false 则之后的过滤器和动作不会执行
    • 继承 yii\base\ActionFilter 类并覆盖 beforeAction() 或 afterAction() 方法来创建动作的过滤器
  • 核心过滤器(类似于java的概念,laravel中的是中间件)

    • Yii 核心过滤器在 yii\filters 命名空间下
    • AccessControl 提供基于 rules 规则的访问控制
      • 决定允许还是拒绝请求动作的执行,若无答合的规则,则访问被拒绝
      • 应用场景 比如用户 IP 地址、登录状态等等)的规则,
    • 认证方法过滤器
      • 认证方法过滤器类在 yii\filters\auth 命名空间下
      • 认证方法过滤器通过 HTTP Basic Auth 或 OAuth 2 来认证一个用户
      • 如 yii\filters\auth\HttpBasicAuth 来认证一个用户
        • user identity class 类必须 实现 findIdentityByAccessToken() 方法
      • ContentNegotiator 支持响应内容格式处理和语言处理
        • 通过 GET 参数和 Accept HTTP 头部来决定响应内容格式和语言
        • 亦可在应用主体上配置。
        • 如果请求中没有检测到内容格式和语言, 使用 formats 和 languages 第一个配置项
    • HttpCache 利用 Last-Modified 和 Etag HTTP 头实现客户端缓存
    • PageCache 实现服务器端整个页面的缓存
    • RateLimiter 根据 漏桶算法 来实现速率限制,主要用在实现 RESTful APIs
    • VerbFilter 检查请求动作的 HTTP 请求方式是否允许执行, 如果不允许,会抛出 HTTP 405异常
    • Cors filter 应在授权/认证过滤器之前定义, 以保证 CORS 头部被发送
    • 若要将CORS过滤器添加到 API 中的 yii\rest\ActiveController 类, 还要检查 REST Controllers 中的部分

小部件Widgets

  • 在视图中使用的可重用单元, 使用面向对象方式创建复杂和可配置用户界面单元
  • Yii提供许多优秀的小部件
    • 比如 active form,menu, jQuery UI widgets, Twitter Bootstrap widgets
  • 使用
    • 在视图中可调用 yii\base\Widget::widget() 方法使用小部件
    • 小部件会在 begin() 和 end() 执行处分别起止标签

调用 yii\base\Widget::end() 的时候,一些小部件将使用 输出缓冲 来调整封闭的内容

  • 小部件的全局默认值可以通过 DI 容器配置, 如 \Yii::$container->set(xx,yy)
  • 创建小部件
    1. widget() 方法
      • 继承 yii\base\Widget 类,覆盖 init() 或 run() 方法
      • 前者属性赋值,后者返回小部件生成渲染结果的代码,通常大段代码采用 render 方法
    2. begin() 和 end() 方法
      • PHP 输出缓冲 ob_start() 在 init() 启动
      • 所有在 init() 和 run() 方法之间的输出内容都会被获取,并在 run() 处理和返回
  • 流程
    • begin 时会创建 一个新的小部件实例,并在构造结构时调用init 方法
    • 在 end 方法时,会调用 run 方法并输出结果
  • 小结
    • 通常逻辑代码在小部件类,展示内容在视图中
    • 小部件设计是独立的,丢弃它不需要额外的处理
    • 小部件是可以重用的类,视图只是应用中使用的普通PHP脚本

前端资源(Assets)

  • Yii 中的资源是和 Web 页面相关的文件,通常放在 web 可访问的目录下,直接被 Web 服务器调用

  • 在视图中注册一个资源包, 在渲染 Web 页面时会包含包中的 CSS 和 JavaScript 文件

  • 定义资源包

    • 资源包 放在一个目录下的资源集合
    • 资源包指定为继承 yii\web\AssetBundle 的 PHP 类, 包名为可自动加载的 PHP 类名
    • 在资源包类中,要指定资源所在位置,包含的文件,以及其他包的依赖关系
  • 资源位置

    • 源资源,发布资源,外部资源
    • 推荐 指定 basePath 而不是 sourcePath
  • 资源依赖 通过 $depends 属性来指定

  • 资源选项

    • 可指定 cssOptions 和 jsOptions 属性来自定义页面包含 CSS 和 JavaScript 文件的方式,
    • 这些属性值会分别传递给 yii\web\View::registerCssFile() 和 yii\web\View::registerJsFile() 方法
    • 默认情况下,当发布资源包时,所有在 yii\web\AssetBundle::$sourcePath 目录里的内容都会发布
  • 使用资源包

    • 在视图中调用 yii\web\AssetBundle::register() 方法注册资源
    • 在视图模板可使用如下代码注册资源包
      • use app\assets\AppAsset;AppAsset::register($this);
      • 在其他地方注册资源包,应提供视图对,如在小部件类中注册资源包, 可以通过 $this->view 获取视图对象
  • 动态资源包

    • 应用场景 语言本地化覆盖 yii\web\AssetBundle::init() 方法来实现
    • 特定资源包 通过 yii\web\AssetBundle::register() 返回的实例进行调整
  • 自定义资源包 assetManager

    • Yii 通过配置名为 assetManager 的应用组件来使用 yii\web\AssetManager, 配置 $bundles属性自定义资源包行为
    • 在应用配置中配置 assetManager设置cdn资源, sourcePath则一定不要发布该资源
    • 资源包组件-->管理器-->bundles-->资源包类名-->对应的配置数组
    • 在 yii\web\AssetBundle::init() 方法内或在注册的资源包对象上进行的调整优先于 AssetManager 配置
  • 资源映射 “修复”多个资源包中资源文件的错误或者不兼容 $assetMap 属性

  • 发布资源 assetManager

    • 可 basePath 和 baseUrl 属性自定义发布位置
    • 可使用符号链接(若系统允许)'linkAssets' => true,
    • 资源包放在 Web 不能访问的目录, 当视图注册资源时资源会被拷贝到一个 Web 可访问的目录中
  • 清除缓存 'appendTimestamp' => true

  • 常用资源包

    • yii\web\YiiAsset 包含 yii.js 文件
    • yii\web\JqueryAsset 包含 jQuery Bower 包的 jquery.js 文件
    • yii\bootstrap\BootstrapAsset 包含 Twitter Bootstrap 框架的 CSS 文件
    • yii\bootstrap\BootstrapPluginAsset JavaScript 文件
    • yii\jui\JuiAsset 包含 jQuery UI 库的 CSS 和 JavaScript 文件
  • 资源转换

    • yii\web\AssetManager::$converter 自定义预处理命令和支持的扩展语法
    • yii\web\AssetConverter::$commands 属性指定支持的扩展语法
  • 合并和压缩

    • asset manager 资源管理器
    • asset 命令 自动处理资源包命令(生成相应配置文件)
      • yii asset/template assets.php
      • jsCompressor 和 cssCompressor定控制台命令或PHP回调函数来处理合并和压缩
    • 资源包分组
      • 指出输出的bundles包分组, allShared,allBackEnd,allFrontEnd

扩展

  • 类的自举引导
    • bootstrapping class (自举类)实现 yii\base\BootstrapInterface 接口
    • 实现 bootstrap 方法,接收主体应用参数, 置于 myname\mywidget命名空间之下
    • 应用场景 扩展可响应应用的 beginRequest 事件,做一些环境的设置工作
    • 将自举类在 composer.json 文件中列出来,每一个请求的自举过程中,自动实例化自举类并调用其 bootstrap() 方法
  • 操作数据库
    • 在需要访问数据库的类中申明一个 db 属性,该属性扩展使用哪个DB连接
    • 提供 数据迁移 来操作数据库的结构修改,而不是使用SQL文本文件
    • 尽量使迁移文件适用于不同的 DBMS
    • 在迁移文件中避免使用 Active Record
  • 使用Assets
    • 手动这些 asset 文件拷贝到特定的 Web 可以读取的文件夹
    • 申明一个 asset bundle 并依靠 asset 发布机制自动将这些文件
  • 国际化和本地化
    • 扩展为终端用户显示信息,这些信息应该用 Yii::t() 包装起来,以便可以进行翻译
    • 若扩展显示数字、日期等,用 yii\i18n\Formatter 中适当的格式化规则做格式化
本作品采用《CC 协议》,转载必须注明作者和本文链接
pardon110
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
开发者 @ 社科大
文章
134
粉丝
24
喜欢
101
收藏
55
排名:106
访问:8.9 万
私信
所有博文
社区赞助商