新闻详情

新闻详情

首页 / 资讯中心 / 详情

Yii 2 配置系统完全指南:创建对象、应用配置、默认配置与环境常量

发布时间:2026/9/24 23:52:40来源:尧图网络
Yii 2 配置系统完全指南:创建对象、应用配置、默认配置与环境常量
Yii 2 配置系统完全指南创建对象、应用配置、默认配置与环境常量【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址: https://gitcode.com/gh_mirrors/yi/yii2配置Configuration是 Yii 2 框架最核心的基础设施之一无论是创建数据库连接、初始化应用组件还是定制小部件、挂载事件与行为都统一通过配置数组完成。本篇指南以 docs/guide-zh-CN/concept-configurations.md 为骨架结合框架源码framework/BaseYii.php、framework/di/Container.php、framework/base/Component.php深入讲解配置格式、Yii::createObject()与Yii::configure()的底层实现、应用与小部件配置、配置文件的组织方式、基于依赖注入容器的默认配置以及按环境切换配置的YII_ENV常量体系。读完本篇你将能熟练写出结构清晰、可维护、按环境差异化生效的 Yii 2 配置。什么是配置创建对象与初始化对象在 Yii 中创建新对象和初始化已存在对象时都会广泛使用配置。一个配置通常包含三部分信息被创建对象的类名一组将要赋值给对象属性的初始值可选的一组将被附加到对象事件上的事件句柄以及一组将被附加到对象上的行为。以下代码用配置创建并初始化一个数据库连接$config [ class yii\db\Connection, dsn mysql:host127.0.0.1;dbnamedemo, username root, password , charset utf8, ]; $db Yii::createObject($config);Yii::createObject()接受一个配置数组根据其中class元素指定的类名实例化对象对象创建完成后剩余参数被用于初始化属性、事件处理和行为。对于已存在的对象可以使用Yii::configure()方法依据配置去初始化其属性Yii::configure($object, $config);注意当配置用于初始化一个已存在的对象时配置数组中不应该再包含class元素否则会触发不必要的类解析逻辑。源码视角createObject 与 configure 的实现在 framework/BaseYii.php 中Yii::createObject()的静态实现体现了框架对配置类型的宽容处理传入字符串时视为类名直接交给static::$container-get($type, $params)由依赖注入容器解析传入**可调用对象callable**时使用static::$container-invoke()执行传入数组时读取其中的class键或__class键得到类名将其从配置中移除后把剩余配置作为$config参数传给Container::get()若数组缺少class/__class键则抛出InvalidConfigException提示对象配置必须是包含 class 或 __class 元素的数组。而Yii::configure()framework/BaseYii.php的实现非常朴素——遍历配置数组逐一执行$object-$name $value。赋值的落地效果取决于对象基类对于继承 framework/base/BaseObject.php 的普通对象__set()会优先调用对应的setXxx()方法若只有 getter 没有 setter 则视为只读属性抛出InvalidCallException两者皆无则抛出UnknownPropertyException。这一机制正是只有公共成员变量以及通过 getter/setter 定义的属性可以被配置这一规则的本质来源。配置的格式Configuration Format一个配置数组的完整格式可以描述为[ class ClassName, propertyName propertyValue, on eventName $eventHandler, as behaviorName $behaviorConfig, ]其中各元素的语义如下元素含义注意事项class将要创建对象的完全限定类名仅用于创建新对象配置已存在对象时须省略propertyName对象属性的初始值键名是属性名只有公共成员变量以及通过 getter/setter 定义的属性可被配置on eventName附加到对象事件上的句柄键名由on前缀 事件名组成事件句柄格式见事件章节as behaviorName附加到对象的行为键名由as前缀 行为名组成$behaviorConfig是创建行为的配置格式与普通配置相同下面是一个同时配置了属性初值、事件句柄和行为的完整示例[ class app\components\SearchEngine, apiKey xxxxxxxx, on search function ($event) { Yii::info(搜索的关键词 . $event-keyword); }, as indexer [ class app\components\IndexerBehavior, // ... 初始化属性值 ... ], ]源码视角on 与 as 前缀如何被解析on与as前缀并不是配置数组的魔法语法而是由组件基类的__set()魔术方法在赋值阶段分流的。framework/base/Component.php 中__set()的判定顺序为存在setXxx()setter → 走属性赋值键名以on开头前 3 个字符→ 截取eventName并调用$this-on(trim(substr($name, 3)), $value)绑定事件处理器on()的实现见 framework/base/Component.php支持通配符事件与追加/前置两种挂载策略键名以as开头 → 截取行为名并根据值类型决定如何创建行为Behavior实例直接附加Closure调用闭包得到行为实例配置数组或类名字符串通过Yii::createObject()创建并校验其确实是Behavior的子类否则抛出InvalidConfigException。最终统一交由attachBehavior()framework/base/Component.php挂载。这也解释了为什么行为值既可以是对象、配置数组也可以是行为类名的字符串——__set()对这三种形态都做了兼容。使用配置Using Configurations配置在 Yii 中几乎无处不在最常见的两大使用场景是配置应用与配置小部件。应用的配置Application Configurations应用的配置可能是最复杂的一类配置yii\web\Application类拥有大量可配置属性和事件更重要的是它的components属性可以接收配置数组并由应用注册为可全局访问的服务定位器组件。以下是针对基础应用模板的应用配置概要$config [ id basic, basePath dirname(__DIR__), extensions require __DIR__ . /../vendor/yiisoft/extensions.php, components [ cache [ class yii\caching\FileCache, ], mailer [ class yii\swiftmailer\Mailer, ], log [ class yii\log\Dispatcher, traceLevel YII_DEBUG ? 3 : 0, targets [ [ class yii\log\FileTarget, ], ], ], db [ class yii\db\Connection, dsn mysql:hostlocalhost;dbnamestay2, username root, password , charset utf8, ], ], ];注意此配置中没有class键因为应用类名已在入口脚本中显式指定(new yii\web\Application($config))-run();这种入口脚本给类名、配置数组给属性的分工正对应前面提到的规则已知类名时配置不再需要class元素。自版本 2.0.11 起系统配置还支持使用container属性来配置依赖注入容器$config [ id basic, basePath dirname(__DIR__), extensions require __DIR__ . /../vendor/yiisoft/extensions.php, container [ definitions [ yii\widgets\LinkPager [maxButtonCount 5] ], singletons [ // 依赖注入容器单例配置 ] ] ];其中definitions定义类可带属性配置的创建规则singletons定义单例类——两者最终都会注册进容器使后续Yii::createObject()创建的对象自动应用这些规则。更完整的definitions与singletons用法参见依赖注入容器章节下的高级应用实例。小部件的配置Widget Configurations使用小部件时通常需要传入配置以自定义其属性。yii\base\Widget::widget()和yii\base\Widget::begin()都可以接受配置数组use yii\widgets\Menu; echo Menu::widget([ activateItems false, items [ [label Home, url [site/index]], [label Products, url [product/index]], [label Login, url [site/login], visible Yii::$app-user-isGuest], ], ]);上述代码创建了一个yii\widgets\Menu小部件将其activateItems属性初始化为falseitems属性配置为要渲染的菜单项。请注意代码中已经写出了类名yii\widgets\Menu配置数组不应再包含class键。Menu::widget()内部正是通过Yii::createObject()或new static()Yii::configure()把这段配置应用到小部件实例上的。配置文件Configuration Files当配置内容十分复杂时通用做法是把配置存储在一个或多个 PHP 文件中这些文件被称为配置文件。一个配置文件返回一个 PHP 数组。例如把应用配置存储在web.php中return [ id basic, basePath dirname(__DIR__), extensions require __DIR__ . /../vendor/yiisoft/extensions.php, components require __DIR__ . /components.php, ];鉴于components配置本身也很复杂可以把它们拆到独立的components.php中再通过require合并进web.phpreturn [ cache [ class yii\caching\FileCache, ], mailer [ class yii\swiftmailer\Mailer, ], log [ class yii\log\Dispatcher, traceLevel YII_DEBUG ? 3 : 0, targets [ [ class yii\log\FileTarget, ], ], ], db [ class yii\db\Connection, dsn mysql:hostlocalhost;dbnamestay2, username root, password , charset utf8, ], ];在入口脚本中只需一条require即可取得配置内容并启动应用$config require path/to/web.php; (new yii\web\Application($config))-run();这种按职责拆分 require 合并的组织方式是 Yii 2 高级模板advanced template多环境、多入口配置管理的基础例如common/config/main.php与console/config/main.php分别面向 Web 与控制台入口复用同一套组件配置。默认配置Default ConfigurationsYii::createObject()基于依赖注入容器实现。因此你可以在入口脚本中调用Yii::$container-set()给指定类的所有实例附加一系列默认配置之后每次通过Yii::createObject()创建该类的对象时默认配置都会自动合并生效。例如想让分页器小部件yii\widgets\LinkPager最多只显示 5 个翻页按钮默认是 10 个只需在入口脚本中写\Yii::$container-set(yii\widgets\LinkPager, [ maxButtonCount 5, ]);不使用默认配置的话你就不得不在每个使用分页器的地方重复配置maxButtonCount的值。源码视角set 与 setSingleton 的注册机制Container::set()framework/di/Container.php将规范化后的类定义存入_definitions并清除已有的单例缓存Container::setSingleton()framework/di/Container.php与之类似但额外标记为单例——后续每次get()都返回同一实例。当Yii::createObject()携带配置调用Container::get()时framework/di/Container.php若该类注册过 definition且 definition 是数组框架会先取出class键得到具体类把 definition 的其余部分与本次调用传入的$config通过array_merge合并调用侧配置优先再进入构建流程构建过程由build()framework/di/Container.php完成通过反射解析构造函数依赖、合并构造参数最终若对象实现了yii\base\Configurable接口则将配置作为构造函数最后一个参数传入否则在new之后逐一对$object-$name $value赋值。也就是说默认配置之所以能作用于所有LinkPager实例正是因为widgets内部创建小部件时统一走Yii::createObject()而容器在构建阶段把注册的 definition 与调用侧配置做了合并。该行为的自动化验证可参见 tests/framework/di/ContainerTest.php 中关于依赖与定义解析的测试用例。环境常量Environment Constants配置经常需要随应用运行环境而变化。例如开发环境使用名为mydb_dev的数据库生产环境则使用mydb_prod。为此Yii 提供了定义在入口脚本中的YII_ENV常量defined(YII_ENV) or define(YII_ENV, dev);YII_ENV可取以下任一值值环境派生常量prod生产环境YII_ENV_PROD为true若未显式定义YII_ENV的默认值就是proddev开发环境YII_ENV_DEV为truetest测试环境YII_ENV_TEST为true有了这些环境常量就可以针对当前运行环境做差异化配置。例如只在开发环境中启用调试工具模块$config [...]; if (YII_ENV_DEV) { // 根据 dev 环境进行的配置调整 $config[bootstrap][] debug; $config[modules][debug] yii\debug\Module; } return $config;源码视角环境常量的派生规则在 framework/BaseYii.php 中框架用defined(YII_ENV) or define(YII_ENV, prod)兜底默认值为prod再根据YII_ENV的具体取值派生出三个布尔常量YII_ENV_PROD⇔YII_ENV prodYII_ENV_DEV⇔YII_ENV devYII_ENV_TEST⇔YII_ENV test因此入口脚本只需在vendor/autoload.php加载、框架文件被执行之前即BaseYii.php首次加载之前定义好YII_ENV整个应用便能据此切换数据库、日志、缓存乃至调试模块。生产环境部署时若不做任何定义YII_ENV也会自动回落到prod保证安全默认。进阶技巧与常见误区配置对象时的class键取舍Yii::createObject()创建新对象必须提供class或__classYii::configure()与已知类名的小部件配置则绝不能带class否则容器会重新解析类名并可能覆盖你的实例。属性赋值走 setter 而非直接写字段由于__set()优先调用setXxx()配置数组的键名可以与公共属性名不同例如配置onRequest时实际调用setOnRequest()同时只读属性只有 getter会抛异常配置前请先确认属性可写。on/as键名必须保留前缀与空格on search不是onsearch前缀解析依赖strncmp($name, on , 3)这类精确匹配。默认配置与 DI 容器配置合并顺序注册在容器的 definition 先合并调用侧传入的配置数组后合并、优先级更高可用于对默认配置做局部覆盖。多环境配置文件组织可结合按职责拆分main/params/console 按环境覆盖web.php与web-local.php、YII_ENV条件分支的组合方式实现与高级模板一致的环境隔离。总结配置是 Yii 2 一切对象创建与初始化的统一入口Yii::createObject()负责按配置建对象Yii::configure()负责按配置改对象on/as前缀让配置天然支持事件与行为挂载Yii::$container-set()让默认配置全局生效YII_ENV系列常量让配置随环境自动切换。把这一套机制吃透无论是写入口脚本、组织应用组件还是定制第三方小部件都能做到结构清晰、改动局部化、环境切换零成本。文中涉及的源码均可在本仓库 framework/BaseYii.php、framework/di/Container.php、framework/base/Component.php 中查阅相关概念可继续阅读属性、事件、行为与依赖注入容器章节。【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址: https://gitcode.com/gh_mirrors/yi/yii2创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

汽车电子底层软件开发:AUTOSAR与CAN总线实战解析 2026/9/24 23:59:54

汽车电子底层软件开发:AUTOSAR与CAN总线实战解析

1. 这门“汽车电子底层软件开发就业课”到底在教什么?——不是写个LED闪烁就能上岗的很多人看到“汽车电子底层软件开发就业课”这个标题,第一反应是:不就是嵌入式C语言单片机CAN通信?刷几道LeetCode、调通一个STM32 CAN收发例程&…

阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战 2026/9/24 23:59:54

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署 2026/9/24 23:59:54

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

阅读更多 →
AI元人文:从工具使用到思维重构的深度探索 2026/9/24 23:59:54

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

阅读更多 →
《AI Agent 场景应用 - MobileOpenClaw》第5-9节:会话上下文细化处理实战指南 2026/9/24 23:59:47

《AI Agent 场景应用 - MobileOpenClaw》第5-9节:会话上下文细化处理实战指南

文档教程后端 【免费下载链接】CodeGuide :books: 本代码库是作者小傅哥多年从事一线互联网 Java 开发的学习历程技术汇总,旨在为大家提供一个清晰详细的学习教程,侧重点更倾向编写Java核心内容。如果本仓库能为您提供帮助,请给予支持(关注、…

阅读更多 →
写出来的,和没写的——七个模块,一副骨头 2026/9/24 23:59:47

写出来的,和没写的——七个模块,一副骨头

「合金日记」第 85 篇 「小艾说」第 34 期 幕后弧(换弧开篇) 从「写谁」转向「怎么写」 专栏连载中 前篇:《听漏了,还是听深了——一个 a,一句禅》 模块 骨架 沉默 对位 骨头 没看过前篇也能读 没看过前八十…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞