- 后端
- Web框架
【免费下载链接】yii2
Yii 2: The Fast, Secure and Professional PHP Framework
本文是 Yii2 框架应用结构的总览指南,系统梳理 Yii 应用如何按照「模型-视图-控制器(MVC)」架构模式组织,以及入口脚本、应用、应用组件、模块、过滤器、部件(Widget)等七大核心实体的职责与协作关系。读完本文,你将掌握 Yii2 应用的静态结构全貌,理解每个实体的源码级定位(framework/base/Model.php、framework/base/Controller.php 等),并为深入研读各实体专项文档打下基础。
一、MVC 架构:Yii 应用的骨架
Yii 应用按照经典的 模型-视图-控制器(MVC) 架构模式组织,整个体系围绕三个核心角色分工协作:
- 模型(Models):代表业务数据、业务逻辑与业务规则。例如
ContactForm这类用于收集表单输入的类,或Post这类对应数据库表的 ActiveRecord 类。在 模型详解 中可以看到,模型可提供属性(Attributes)、属性标签(Attribute Labels)、场景(Scenarios)、验证规则(Validation Rules)、批量赋值(Massive Assignment)与数据导出(Data Exporting)等能力。 - 视图(Views):负责将模型数据以用户期望的格式呈现出来。Web 应用中视图通常是以 HTML 为主、混有展示型 PHP 代码的模板文件,由
view应用组件统一管理渲染。详见 视图详解。 - 控制器(Controllers):接收来自用户的输入,并将其转化为对模型和视图的命令。控制器负责分析请求数据、传递给模型、把模型结果注入视图,最终生成响应。详见 控制器详解。
从源码结构可以印证这一分工:Model继承自Component并实现ArrayAccess、IteratorAggregate等接口(framework/base/Model.php),使其既能以对象属性方式访问,也能以数组方式访问;Controller继承自Component并实现ViewContextInterface(framework/base/Controller.php),从而能够为视图提供渲染上下文。
二、除 MVC 之外的七大核心实体
除了 MVC 三角色,Yii 应用还包含以下实体,它们共同构成一个完整的应用系统。下图展示了 Yii 应用的静态结构:
1. 入口脚本(Entry Scripts)
入口脚本是直接暴露给最终用户的 PHP 脚本,负责启动整个请求处理周期。每个应用(无论是 Web 应用还是控制台应用)都有且仅有一个入口脚本:Web 应用通常命名为index.php并放置在 Web 可访问目录下;控制台应用通常命名为yii(带.php后缀),放置在应用的 basePath 下,可通过./yii <route> [arguments] [options]执行。
入口脚本的核心工作包括:定义全局常量、注册 Composer 自动加载器、引入 Yii 类文件、加载应用配置、创建并配置应用实例、调用应用的run()方法处理请求。典型 Web 入口脚本代码如下(来自 入口脚本详解):
<?php defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_ENV') or define('YII_ENV', 'dev'); // 注册 Composer 自动加载器 require __DIR__ . '/../vendor/autoload.php'; // 引入 Yii 类文件 require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php'; // 加载应用配置 $config = require __DIR__ . '/../config/web.php'; // 创建、配置并运行应用 (new yii\web\Application($config))->run();其中三个全局常量值得注意:YII_DEBUG(是否调试模式,默认false)、YII_ENV(运行环境,默认prod)、YII_ENABLE_ERROR_HANDLER(是否启用 Yii 内置错误处理器,默认true)。
2. 应用(Applications)
应用是管理 Yii 应用系统整体结构与生命周期的对象。每个应用系统包含唯一一个应用对象,它在入口脚本中创建,并通过\Yii::$app全局访问。应用分为两类:处理 Web 请求的yii\web\Application与处理控制台命令的yii\console\Application。
入口脚本创建应用的方式如下:
require __DIR__ . '/../vendor/autoload.php'; require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php'; // 加载应用配置 $config = require __DIR__ . '/../config/web.php'; // 实例化并配置应用 (new yii\web\Application($config))->run();应用配置是 Yii 配置体系中非常重要的一环,涉及id、basePath、components、modules、bootstrap、catchAll、language、timeZone等众多属性。例如,通过components注册缓存与用户认证组件:
[ 'components' => [ 'cache' => [ 'class' => 'yii\caching\FileCache', ], 'user' => [ 'identityClass' => 'app\models\User', 'enableAutoLogin' => true, ], ], ]应用还触发beforeRequest、afterRequest、beforeAction、afterAction等生命周期事件,供开发者拦截请求处理过程。完整说明见 应用详解。
3. 应用组件(Application Components)
应用本身是服务定位器(Service Locator),承载一组提供各种服务能力的"应用组件"。每个组件有唯一 ID,通过\Yii::$app->componentID访问;组件在第一次被访问时才实例化,后续访问返回同一实例。例如\Yii::$app->db获取数据库连接,\Yii::$app->cache获取缓存组件。
注册方式支持类名、配置数组与匿名函数三种形式:
[ 'components' => [ // 使用类名注册 'cache' => 'yii\caching\ApcCache', // 使用配置数组注册 'db' => [ 'class' => 'yii\db\Connection', 'dsn' => 'mysql:host=localhost;dbname=demo', 'username' => 'root', 'password' => '', ], // 使用匿名函数注册 'search' => function () { return new app\components\SolrService; }, ], ]Yii 预定义了一批固定 ID 的核心应用组件,如request、response、db、log、cache、user、session、view、urlManager等,它们正是 Yii 应用能够处理用户请求的基础。详见 应用组件详解。
4. 模块(Modules)
模块是自包含的软件单元,内部完整包含模型、视图、控制器等全部 MVC 资源,可视为"迷你应用"。与应用的区别在于:模块不能独立部署,必须寄居在应用之内;一个应用可以由多个模块组织而成。
模块的典型目录结构如下:
forum/ Module.php // 模块类文件 controllers/ // 控制器类文件 DefaultController.php // 默认控制器类文件 models/ // 模型类文件 views/ // 控制器视图与布局文件 layouts/ // 布局视图文件 default/ // DefaultController 的视图文件 index.php // index 视图文件每个模块必须有唯一的模块类,继承自yii\base\Module。从源码看,Module直接继承自ServiceLocator(framework/base/Module.php),这与应用一致——模块同样承载组件并共享数据。模块类示例:
namespace app\modules\forum; class Module extends \yii\base\Module { public function init() { parent::init(); $this->params['foo'] = 'bar'; // ... 其他初始化代码 ... } }在应用中通过modules配置项注册模块,即可通过路由ModuleID/ControllerID/ActionID访问模块内的动作。详见 模块详解。
5. 过滤器(Filters)
过滤器是在控制器动作执行前后运行的代码对象。例如:访问控制过滤器在动作执行前校验用户是否有权访问;内容压缩过滤器在动作执行后压缩响应内容再发送给用户。过滤器本质上是一类特殊的行为(Behavior),因此在控制器中通过重写behaviors()方法声明:
public function behaviors() { return [ [ 'class' => 'yii\filters\HttpCache', 'only' => ['index', 'view'], 'lastModified' => function ($action, $params) { $q = new \yii\db\Query(); return $q->from('user')->max('updated_at'); }, ], ]; }默认情况下控制器声明的过滤器作用于该控制器全部动作,可通过only/except属性精确限定。过滤器也可在模块或应用层声明,此时作用于其下所有控制器动作(only/except中应使用路由而非动作 ID)。Yii 在yii\filters命名空间下提供了一批常用过滤器,如AccessControl、HttpCache、PageCache等;自定义过滤器可继承yii\base\ActionFilter并重写beforeAction()/afterAction()。详见 过滤器详解。
6. 部件(Widgets)
部件是可以嵌入视图的对象,可包含控制器逻辑,并能在不同视图中复用。在 视图详解 中可以看到,部件常作为视图的构建块。从源码看,Widget继承自Component并实现ViewContextInterface(framework/base/Widget.php),这使得部件拥有独立的视图目录并能渲染自己的视图模板。
典型用法如ActiveForm、Breadcrumbs、GridView等:
<?= yii\widgets\Breadcrumbs::widget([ 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], ]) ?>7. 视图层补充:布局、主题与部件协作
虽然视图属于 MVC 中的 V 角色,但其组织方式直接关系到整个应用结构的整洁度。Yii 约定:控制器渲染的视图默认放在@app/views/ControllerID目录;布局(Layout)默认放在@app/views/layouts;部件视图放在WidgetPath/views目录。控制器通过render()、renderPartial()、renderAjax()、renderFile()等方法渲染视图,其中render()会套用布局。view应用组件还支持主题(theming)、片段缓存(fragment caching)、客户端脚本管理、资源包(asset bundle)管理等高级能力,详见 视图详解。
三、实体间的协作:一次请求的处理链路
上述实体并非孤立存在,而是围绕一次请求紧密协作。从 框架源码 Application::run() 可以看到请求处理的核心流程:
- 入口脚本加载应用配置,创建应用实例(
preInit()配置basePath等高优先级属性,随后注册错误处理器、配置应用属性、init()中执行bootstrap()启动引导组件); - 入口脚本调用
run():先触发EVENT_BEFORE_REQUEST事件,随后handleRequest()将请求解析为路由并创建对应的模块、控制器、动作对象执行之; - 动作执行前后,应用、模块、控制器按序触发
beforeAction/afterAction事件,过滤器(本质是行为)在这些环节被织入执行; - 触发
EVENT_AFTER_REQUEST事件后发送响应,入口脚本取得退出状态码,完成请求处理。
在控制器内部,动作执行同样经历固定生命周期:init()→ 创建动作对象(根据动作 ID 匹配actions()动作映射或actionXxx()内联动作方法)→ 依次调用应用、模块、控制器的beforeAction()→ 运行动作并填充动作参数 → 逆序调用afterAction()→ 应用将动作结果写入响应。完整生命周期见 控制器详解。
四、最佳实践与设计原则
Yii 官方指南对各实体给出了明确的职责边界建议,遵循这些原则能让应用结构保持健康:
- 模型(Models):模型应"胖"于控制器。模型可包含属性、验证规则与业务逻辑方法,但不应直接访问
request、session等环境数据(应由控制器注入),也应避免嵌入 HTML 等展示代码(交给视图)。 - 控制器(Controllers):控制器应保持"瘦",每个动作通常只有几行代码。控制器可访问请求数据、调用模型与服务组件方法、使用视图组装响应,但不应处理请求数据(属于模型层职责),也不应嵌入展示代码。
- 视图(Views):视图主要包含展示代码(HTML 与简单的遍历、格式化、渲染 PHP 代码),不应执行数据库查询(属于模型职责),不应直接访问
$_GET/$_POST(属于控制器职责),可以读取模型属性但不应修改。 - 过滤器与部件:过滤器适合横切关注点(鉴权、缓存、压缩),部件适合可复用的 UI 逻辑块;二者都能显著提升代码复用度。
五、继续深入:相关文档导航
本文是 Yii2 应用结构的"地图",各实体的深入讲解见下列专项文档(均位于 docs/guide-uk/ 目录):
- 模型(Models)详解
- 视图(Views)详解
- 控制器(Controllers)详解
- 入口脚本(Entry Scripts)详解
- 应用(Applications)详解
- 应用组件(Application Components)详解
- 模块(Modules)详解
- 过滤器(Filters)详解
- 部件(Widgets)详解
对应框架源码位于 framework/base/(Application、Module、Controller、Model、Widget等基类)与 framework/web/(Web 应用与 Web 组件实现),可供读者对照研读,从实现层面验证本文所述的架构设计。
- 后端
- Web框架
【免费下载链接】yii2
Yii 2: The Fast, Secure and Professional PHP Framework
相关推荐
Appium 驱动与插件管理详解:Extension CLI 与 npm 两种策略及源码实现解析
Appium 驱动与插件管理详解:Extension CLI 与 npm 两种策略及源码实现解析 要在 Appium 上完成任何实际的自动化工作,至少需要安装一
后端Web框架Yii 2 应用结构全景:MVC 架构与六大核心实体详解
Yii 2 应用结构全景:MVC 架构与六大核心实体详解 导读 本文基于 Yii 2 官方指南的总览章节(对应仓库中的 docs/guide id/struct
后端Web框架Yii 2 应用结构全景:MVC 架构与六大核心组成实体详解
Yii 2 应用结构全景:MVC 架构与六大核心组成实体详解 本文基于 Yii 2 官方指南的《应用结构总览》( docs/guide pl/structure
后端Web框架
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考