Yii2 应用结构总览:MVC 架构与七大核心实体深入解析
2026/9/23 11:51:19 网站建设 项目流程
  • 后端
  • Web框架

【免费下载链接】yii2

Yii 2: The Fast, Secure and Professional PHP Framework

项目地址:https://gitcode.com/gh_mirrors/yi/yii2
点击查看免费下载

本文是 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并实现ArrayAccessIteratorAggregate等接口(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 配置体系中非常重要的一环,涉及idbasePathcomponentsmodulesbootstrapcatchAlllanguagetimeZone等众多属性。例如,通过components注册缓存与用户认证组件:

[ 'components' => [ 'cache' => [ 'class' => 'yii\caching\FileCache', ], 'user' => [ 'identityClass' => 'app\models\User', 'enableAutoLogin' => true, ], ], ]

应用还触发beforeRequestafterRequestbeforeActionafterAction等生命周期事件,供开发者拦截请求处理过程。完整说明见 应用详解。

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 的核心应用组件,如requestresponsedblogcacheusersessionviewurlManager等,它们正是 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命名空间下提供了一批常用过滤器,如AccessControlHttpCachePageCache等;自定义过滤器可继承yii\base\ActionFilter并重写beforeAction()/afterAction()。详见 过滤器详解。

6. 部件(Widgets)

部件是可以嵌入视图的对象,可包含控制器逻辑,并能在不同视图中复用。在 视图详解 中可以看到,部件常作为视图的构建块。从源码看,Widget继承自Component并实现ViewContextInterface(framework/base/Widget.php),这使得部件拥有独立的视图目录并能渲染自己的视图模板。

典型用法如ActiveFormBreadcrumbsGridView等:

<?= 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() 可以看到请求处理的核心流程:

  1. 入口脚本加载应用配置,创建应用实例(preInit()配置basePath等高优先级属性,随后注册错误处理器、配置应用属性、init()中执行bootstrap()启动引导组件);
  2. 入口脚本调用run():先触发EVENT_BEFORE_REQUEST事件,随后handleRequest()将请求解析为路由并创建对应的模块、控制器、动作对象执行之;
  3. 动作执行前后,应用、模块、控制器按序触发beforeAction/afterAction事件,过滤器(本质是行为)在这些环节被织入执行;
  4. 触发EVENT_AFTER_REQUEST事件后发送响应,入口脚本取得退出状态码,完成请求处理。

在控制器内部,动作执行同样经历固定生命周期:init()→ 创建动作对象(根据动作 ID 匹配actions()动作映射或actionXxx()内联动作方法)→ 依次调用应用、模块、控制器的beforeAction()→ 运行动作并填充动作参数 → 逆序调用afterAction()→ 应用将动作结果写入响应。完整生命周期见 控制器详解。

四、最佳实践与设计原则

Yii 官方指南对各实体给出了明确的职责边界建议,遵循这些原则能让应用结构保持健康:

  • 模型(Models):模型应"胖"于控制器。模型可包含属性、验证规则与业务逻辑方法,但不应直接访问requestsession等环境数据(应由控制器注入),也应避免嵌入 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/(ApplicationModuleControllerModelWidget等基类)与 framework/web/(Web 应用与 Web 组件实现),可供读者对照研读,从实现层面验证本文所述的架构设计。

  • 后端
  • Web框架

【免费下载链接】yii2

Yii 2: The Fast, Secure and Professional PHP Framework

项目地址:https://gitcode.com/gh_mirrors/yi/yii2
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询