ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Yii2 应用组件(Application Components)完全指南:注册、Bootstrap 与核心组件源码解析

Yii2 应用组件(Application Components)完全指南:注册、Bootstrap 与核心组件源码解析 后端Web框架【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址https://gitcode.com/gh_mirrors/yi/yii2点击查看免费下载Yii2 框架的核心运行机制之一是将各种服务以应用组件Application Components的形式挂载到应用对象上数据库连接、URL 解析、请求响应、日志、缓存、国际化、视图渲染等能力全部由这些组件提供。本文以官方指南 docs/guide/structure-application-components.md及其印尼语译本 docs/guide-id/structure-application-components.md为主体结合框架源码与单元测试系统讲解应用组件的注册方式、懒加载机制、Bootstrap 引导原理以及 Yii2 预置的 14 个核心应用组件。读完本文你将能够熟练配置、定制与诊断任意 Yii2 应用的服务层。一、什么是应用组件应用即服务定位器Yii2 中的应用对象Application本质上是一个 服务定位器Service Locator它持有并管理一组所谓的应用组件这些组件为处理请求提供各类服务。例如urlManager组件负责将 Web 请求路由到对应的控制器db组件提供数据库相关服务cache组件提供缓存能力。每个应用组件都有一个 ID用于在同一应用内唯一标识它。你可以通过下面的表达式直接访问任意已注册的应用组件\Yii::$app-componentID例如// 获取 DB 连接组件yii\db\Connection $db \Yii::$app-db; // 获取应用注册的主缓存组件yii\caching\Cache $cache \Yii::$app-cache;懒加载第一次访问时才实例化应用组件遵循懒加载lazy loading原则组件对象在第一次通过上述表达式被访问时才创建之后的每次访问都会返回同一个组件实例即单例共享。如果一次请求从头到尾都没有访问某个组件该组件就根本不会被实例化从而节省内存与初始化开销。这一机制在 framework/di/ServiceLocator.php 的get()方法中有清晰的实现定位器内部维护_components已实例化对象与_definitions组件定义两张表首次访问时根据定义调用Yii::createObject()创建对象并缓存之后直接返回缓存实例对未注册的 ID 则抛出InvalidConfigExceptionUnknown component ID: xxx。二、注册应用组件三种定义方式应用组件可以是任意对象。你需要在 应用配置 的components属性中注册它们。官方指南给出了三种典型定义方式类名字符串、配置数组、匿名函数。[ components [ // 方式一使用类名注册 cache 组件 cache yii\caching\ApcCache, // 方式二使用配置数组注册 db 组件 db [ class yii\db\Connection, dsn mysql:hostlocalhost;dbnamedemo, username root, password , ], // 方式三使用匿名函数注册 search 组件 search function () { return new app\components\SolrService; }, ], ]三种方式的语义分别对应 framework/di/ServiceLocator.php 中set()方法支持的四种定义类型类名、配置数组、PHP callable、对象实例类名字符串get()时按类名直接创建对象所有属性取默认值配置数组数组中的class键指明类名其余键值对用于初始化对象属性get()时由Yii::createObject()完成创建 配置两步。注意若配置数组缺少class键set()会抛出InvalidConfigException匿名函数Closureget()时调用该函数把返回值作为组件实例适合需要复杂初始化逻辑如依赖注入、参数传递的场景对象实例直接传入已创建的对象get()原样返回。提示虽然你可以随心所欲地注册任意多个应用组件但应当谨慎为之。应用组件类似于全局变量注册过多会让代码难以测试和维护。多数情况下直接在需要的地方创建局部对象并当场使用是更干净的做法。批量注册与覆盖规则setComponents($components)是set()的批量版本见 framework/di/ServiceLocator.php它会遍历传入数组逐个调用set()。如果某个 ID 已被注册新定义会覆盖旧定义传入null定义则可注销组件。三、Bootstrap 引导组件让组件在每个请求都加载如前所述应用组件只有在首次被访问时才会实例化。但有些时候你希望某些组件在每个请求中都提前创建即使它从未被显式访问——典型场景是log日志组件日志分发器需要在整个请求生命周期内收集并分发日志消息。要实现这一点只需把组件 ID 列入应用配置的bootstrap属性即可。例如下面的配置确保log组件在每个请求中都被加载[ bootstrap [ log, ], components [ log [ // log 组件的配置 ], ], ]Bootstrap 的四种条目类型bootstrap数组中的每个条目可以是以下四种形态英文原版指南 docs/guide/structure-application-components.md 补充了 Closure 的用法组件 ID如log若该 ID 已注册为组件则实例化并引导之模块 ID若该 ID 对应已注册的模块则加载该模块类名包含命名空间\的字符串会被视为类名直接Yii::createObject()创建Closure 匿名函数接收$app应用实例作为参数可以返回组件对象也可以不返回任何东西、仅用于在应用初始化后执行一段代码例如注册事件监听、预加载配置等。[ bootstrap [ log, function ($app) { return new ComponentX(); }, function ($app) { // 执行一些初始化代码 return; }, ], components [ log [ // log 组件的配置 ], ], ]源码视角bootstrap 是怎么执行的引导逻辑位于 framework/base/Application.php 的bootstrap()方法中它在应用配置全部就绪后、init()阶段被调用。整个流程分为两大部分扩展引导读取vendor/yiisoft/extensions.php由 Composer 生成为每个扩展注册路径别名若扩展声明了bootstrap且其对象实现了 framework/base/BootstrapInterface.php 的bootstrap($app)方法则调用之应用级引导遍历$this-bootstrap数组按上文四种形态分别处理——Closure 直接执行字符串 ID 优先当作组件has($mixed)为真或模块hasModule($mixed)为真加载含\的类名字符串则createObject()创建最后凡是实现了BootstrapInterface的对象都会调用其bootstrap($app)方法。若某字符串既不是组件也不是模块且不含命名空间将抛出InvalidConfigException。单元测试 tests/framework/base/ApplicationTest.php 的testBootstrap()完整覆盖了普通组件、实现 BootstrapInterface 的组件、模块、Closure四种引导场景并通过日志断言验证引导顺序是理解该机制的最佳参考。四、核心应用组件Yii2 预置的 14 个服务Yii2 定义了一组 ID 固定、配置默认的内置应用组件它们构成应用处理请求的基础设施。你可以像定制普通组件一样覆写它们的配置当你配置核心组件但未显式指定class时框架会自动使用默认类——这一行为由 framework/base/Application.php 的合并逻辑保证preInit()遍历coreComponents()返回的默认定义凡是用户配置里没有的组件直接补全已有但缺少class的则补上默认类名。下面逐一介绍这 14 个核心组件在 Web 应用中全部可用控制台应用略有差异见下文组件 ID默认类职责assetManageryii\web\AssetManager管理资源包asset bundles与资源发布详见 资源管理dbyii\db\Connection数据库连接用于执行 SQL 查询。注意配置该组件时除class外还必须给出dsn等必需属性详见 数据库访问对象DAOerrorHandleryii\web\ErrorHandler处理 PHP 错误与异常详见 错误处理formatteryii\i18n\Formatter数据格式化如数字千分位分隔、日期长格式展示详见 数据格式化i18nyii\i18n\I18N消息翻译与格式化国际化详见 国际化i18nlogyii\log\Dispatcher日志分发器管理日志目标log targets详见 日志maileryii\swiftmailer\Mailer邮件撰写与发送详见 邮件responseyii\web\Response表示发送给用户的响应详见 响应requestyii\web\Request表示用户发来的请求解析为 路由详见 请求sessionyii\web\Session会话信息仅在 Web 应用中可用详见 会话与 CookieurlManageryii\web\UrlManagerURL 解析与生成详见 路由与 URL 生成useryii\web\User用户认证信息仅在 Web 应用中可用详见 认证viewyii\web\View视图渲染支持详见 视图securityyii\base\Security密码哈希、加解密、随机数等安全能力框架级默认组件源码确认Web 与控制台应用的组件差异Web 应用framework/web/Application.php在其coreComponents()中追加了request、response、session、user、errorHandlerWeb 版实现控制台应用framework/console/Application.php则追加了控制台专用的request、response、errorHandler且不提供session与user组件基类framework/base/Application.php提供公共部分log、view、formatter、i18n、urlManager、assetManager、security并在yii\swiftmailer\Mailer类存在时追加mailer说明 mailer 的可用性取决于是否安装 swiftmailer 扩展。这也解释了官方指南中session、user仅在 Web 应用可用的说明在控制台应用里访问\Yii::$app-session会得到未知组件 ID异常。覆盖核心组件的正确姿势由于合并逻辑会自动补默认类你可以在应用配置中只写想覆盖的属性[ components [ db [ class yii\db\Connection, dsn mysql:hostlocalhost;dbnamedemo, username root, password secret, charset utf8mb4, ], cache [ class yii\caching\FileCache, ], ], ]注意db组件与cache、log等不同db的默认定义只提供类名dsn、username、password等属性没有任何可用的默认值因此必须显式配置否则实例化连接时会因缺少 DSN 而报错。五、原理纵览应用组件的完整生命周期结合源码可以把应用组件的生命周期串成一条清晰的链路构造阶段\Yii::$app $this建立全局访问点framework/base/Application.phppreInit()校验必需的id与basePath并将coreComponents()的默认定义与用户components配置合并配置阶段Component::__construct($config)按配置初始化所有属性components数组最终通过ServiceLocator::setComponents()逐项注册为组件定义初始化阶段init()触发bootstrap()依次执行扩展引导与应用bootstrap数组实现 BootstrapInterface 的对象获得应用就绪回调framework/base/Application.php运行阶段run()依次触发beforeRequest→handleRequest→afterRequest→send生命周期事件framework/base/Application.php期间通过\Yii::$app-xxx按需懒加载各组件组件解析ServiceLocator::__get()拦截属性访问has()检查定义后交由get()创建并缓存实例保证同一请求内组件单例复用。六、实战建议与常见误区按需注册避免组件泛滥每次\Yii::$app-xxx都意味着一次全局状态访问。能用局部变量解决的场景如一次性使用某个辅助服务应优先局部创建。bootstrap只放必须每个请求都在线的组件滥用 bootstrap 会破坏懒加载优势拖慢每个请求的启动速度。log、自定义的事件监听器、需要提前注册行为的模块是典型合理用例。覆盖核心组件时注意class与必需属性框架会自动补默认类但db.dsn这类无默认值的属性必须自己提供若替换class要保证新类与默认类兼容如request必须是yii\web\Request的子类。控制台与 Web 组件集合不同在命令行脚本yii命令中访问session、user会抛异常编写跨环境代码时要先判断Yii::$app的应用类型。调试技巧通过日志观察bootstrap执行顺序参考 tests/framework/base/ApplicationTest.php 的断言方式遇到Unknown component ID异常时检查components配置是否被合并逻辑正确解析、组件定义是否为合法类型。应用组件是 Yii2 架构的枢纽理解了它的注册规则、懒加载时机与引导流程就等于掌握了整个框架服务层的开关与调度。结合上文给出的源码路径你可以在 framework/di/ServiceLocator.php、framework/base/Application.php 与对应测试中进一步深入验证每一个结论。赞分享后端Web框架【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址https://gitcode.com/gh_mirrors/yi/yii2点击查看免费下载相关推荐Yii2 应用组件Application Components完全指南注册、引导加载与核心组件源码解析Yii2 应用组件Application Components完全指南注册、引导加载与核心组件源码解析 Yii2 框架的核心运行机制建立在应用组件之上后端Web框架Yii 2 应用组件Application Components完整指南注册、懒加载、Bootstrapping 与核心组件解析Yii 2 应用组件Application Components完整指南注册、懒加载、Bootstrapping 与核心组件解析 应用组件Applica后端Web框架Yii 2 应用组件Application Components全面解析服务定位、注册方式与核心组件配置实战Yii 2 应用组件Application Components全面解析服务定位、注册方式与核心组件配置实战 应用组件Application Compo后端Web框架创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表