0

0

Yii2配置基本概念

小云云

小云云

发布时间:2018-03-27 14:29:56

|

2369人浏览过

|

来源于php中文网

原创

在Yii中创建新对象或者初始化已经存在的对象广泛的使用配置,配置通常包含被创建对象的类名和一组将要赋值给对象的属性的初始值,这里的属性是Yii2的属性。还可以在对象的事件上绑定事件处理器,或者将行为附加到对象上。从而在定义了对象的初始值的同时,充分规定对象的运行时的动态特性。

以下代码中的配置被用来创建并初始化一个数据库连接:

$config = [    'class' => 'yii\db\Connection',    'dsn' => 'mysql:host=127.0.0.1;dbname=demo',   
 'username' => 'root',    'password' => '',    'charset' => 'utf8',
];$db = Yii::createObject($config);

Yii::createObject()是Yii2中最常用的用来创建对象的方法,其内容是从DI Container中去取的对象,在后面的章节中我们会讲到。这个方法方法接受一个配置数组并根据数组中指定的类名创建对象,对象实例化后,剩余的参数被用来初始化对象的属性,事件和行为。

小编提醒:在Yii2.1中,配置数组中用来表示类名的键值由class变成了__class,但是配置的原理是不变的。

对于已存在的对象,可以使用 Yii::configure() 方法根据配置去初始化其属性, 就像这样:

Yii::configure($object, $config);

请注意,如果配置一个已存在的对象,那么配置数组中不应该包含指定类名的 class 元素。

配置是Yii2的一个特色

在编程中,有个非常重要的概念叫“委托”,就是一个对象A可以依靠另一个对象B去完成特定的功能,典型的应用就是策略模式了。要实现“委托”,要有这么个流程:在对象A实例化时注入另一个对象B;A持有对象B;对象A委托对象B去完成特定的功能。“注入”“持有”“委托”都是设计模式中的高频词汇,通过这些操作可以扩展类的功能。

我们看看在别的面向对象语言如Java或者PHP其他框架中经常使用的方式:

class Person
{    private $strategy = null;    public function __construct(TravelStrategy $travel)
    {
        $this->strategy = $travel;
    }    /**
     * 设置旅行的方式.
     */
    public function setTravelStrategy(TravelStrategy $travel)
    {
        $this->strategy = $travel;
    }    /**
     * 旅行.
     */
    public function travel()
    {        //这里实现了“委托”,委托给$this->strategy来实现旅行的具体方式
        return $this->strategy->travelAlgorithm();
    }
}

在实例化或者初始化时,大概就是这么用的:

class Test{
    public function run($argument)
    {
        // 乘坐火车旅行
        $person = new Person(new TrainStrategy());        $person->travel();        // 改骑自行车
        $person->setTravelStrategy(new BicycleStrategy());        $person->travel();
    }
}

Person是一个想要旅行的人,它持有一个具体的交通方式类$strategy,最后旅游就是委托给这个交通方式$strategy来完成的——是骑车还是自驾游还是坐飞机。在使用时先new 一个对象,并且在构造器里面注入一种交通方式初始化旅行的方式,并且我还可以通过Person::setTravelStrategy临时决定改变旅行方式——这是策略模式的应用场景。

我们看看这一行:

$person = new Person(new TrainStrategy());

这种写法大家再也熟悉不过了吧?其实这完成了两步操作:

  • 实例化对象Person,方式是 new

  • 注入外部实例new TrainStrategy()并对$person初始化。注入的可以是实例当然也可以是常量。

但是按照Yii2的风格,就应该是这样的:

class Person extends Component{    private $strategy = null;    /**
     * 旅行.
     */
    public function setTravelStrategy($travel)
    {        if (!($travel instanceof TravelStrategy)) {
            $travel = Yii::createObject($travel);
        }
        $this->strategy = $travel;
    }    /**
     * 旅行.
     */
    public function travel()
    {        
        return $this->strategy->travelAlgorithm();
    }
}

用法就大概是这样的风格:

//用配置创建对象并初始化,选择火车出行
$person = Yii::createObject([    'class' => Person::class,
    'travelStrategy' => [        'class' => TrainStrategy::class
    ]
]);
$person->travel();//用配置重新初始化对象,改骑自行车
$person = Yii::configure($person, [    'travelStrategy' => [        'class' => BicycleStrategy::class
    ]
]);
$person->travel();

上面这个例子,应该可以帮助大家了解Yii2配置的作用和使用方式。其中创建对象的方式不是通过new关键词,而是去依赖注入容器(DI Container)中去获取的,后面我们会讲到。

Yii2框架似乎不太喜欢用“通用”的实例化和初始化的方式,在Yii2框架内部几乎都是通过配置来实现对象的实例化和初始化。这是Yii2的一个风格,当然这种风格看起来更为简洁(前提是你已经熟悉),使用起来则是更为方便。虽说看起来有差异,但是本质上还是一样的,只是注入的方式有一些差别罢了。

配置的格式

一个配置的格式可以描述为以下形式:

[    'class' => 'ClassName',    'propertyName' => 'propertyValue',    'on eventName' => $eventHandler,    'as behaviorName' => $behaviorConfig,
]

其中,

  • class 元素指定了将要创建的对象的完整类名(用Object::class就可以实现)

  • propertyName 元素指定了对象可写属性的初始值

  • on eventName 元素指定了附加到对象事件上的处理器。 请注意,数组的键名由 on 前缀加事件名组成。on和事件名之间只能有一个空格

  • as behaviorName 元素指定了附加到对象的行为。 请注意,数组的键名由 as 前缀加行为名组成。as和行为名之间只能有一个空格。$behaviorConfig 值表示创建行为的配置信息,格式与我们之前描述的配置格式一样。

下面是一个配置了初始化属性值,事件处理器和行为的示例:

[    'class' => 'app\components\SearchEngine',    'apiKey' => 'xxxxxxxx',    'on search' => function ($event) {
        Yii::info("搜索的关键词: " . $event->keyword);
    },    'as indexer' => [        'class' => 'app\components\IndexerBehavior',
        // ... 初始化属性值 ...
    ],
]

配置实现的原理

我们按照这样的约定,就可以通过配置数组去是实例化和初始化对象:

  • 实现Configurable接口,只要你继承BaseObject或者Component,这条都是满足的——无须担心

    Magic AI Avatars
    Magic AI Avatars

    神奇的AI头像,获得200多个由AI制作的自定义头像。

    下载
  • 子类重载__construct方法时,把配置数组放到构造器的最后一个参数:__construct($param1, $param2, ..., $config)

  • 子类在自己的__construct最后,必须调用parent::__construct($config)方法

到底是如何实现的呢?这还得从BaseObject中说起,看看BaseObject的构造器:

public function __construct($config = []){
    if (!empty($config)) {
        Yii::configure($this, $config);
    }    $this->init();
}

我们知道Yii::configure是实现配置的。我们如果每个子类的__construct都按照上面的规范写,那么到最后无异会调用BaseObject::__construct,并且将子类的配置数组$config也传递过来,最终被Yii::configure使用。我们再看看这个方法:

// $object就是即将被配置的对象实例,$properties是配置数组public static function configure($object, $properties){
    //遍历每个参数,将其设置为属性,这里可能调用setter等方法
    foreach ($properties as $name => $value) {        $object->$name = $value;
    }    return $object;
}

这一句$object->$name = $value可能会发生很多故事,可能会调用Component::__setter或者BaseObject::__setter(参看我们前面讲属性,行为,事件的章节)

配置的应用

Yii 中的配置可以用在很多场景,除了我们上面举的例子,最常见的莫过于Yii最大的实例Application的配置了。Application堪称最复杂的配置之一了, 因为 Application 类拥有很多可配置的属性和事件。 更重要的是它的 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:host=localhost;dbname=stay2',            'username' => 'root',            'password' => '',            'charset' => 'utf8',
        ],
    ],
];

配置中没有 class 键的原因是这段配置应用在下面的入口脚本中, 类名已经指定了。

(new yii\web\Application($config))->run();

Application的配置中,比较重要的是components属性的配置了。在components里配置了的,都作为一个单例可以通过Yii::$app->component来访问;

另外,自版本 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' => [            // 依赖注入容器单例配置
        ]
    ]
];

我们这里重点阐述的是配置的原理,并不对Application做过多的配置,只是加深下大家对配置用法的印象而已,关于Application的配置我们以后会有讲到。

配置文件

当配置的内容十分复杂,通用做法是将其存储在一或多个 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 文件中,并且包含在 web.php 里。 components.php 的内容如下:
return [    '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:host=localhost;dbname=stay2',        'username' => 'root',        'password' => '',        'charset' => 'utf8',
    ],
];

如果数据库配置复杂了,你也可以单独拿出来——总之,简洁易维护就行。

仅仅需要 “require”,就可以取得一个配置文件的配置内容,像这样:

$config = require('path/to/web.php');(new yii\web\Application($config))->run();

默认配置

Yii::createObject() 方法基于依赖注入容器实现,你可以通过 Yii::creatObject() 创建对象时实现配置,同样也可以直接调用 Yii::$container->set() 来实现:

\Yii::$container->set('yii\widgets\LinkPager', [    'maxButtonCount' => 5,
]);

环境常量

配置经常会随着环境的更改而更改,有哪些环境呢?——生产,开发,测试。不同的环境可能会提供不同的组件,因此我们可以先定义不同的环境变量。

为了便于切换使用环境,Yii 提供了一个定义在入口脚本中的 YII_ENV 常量。 如下:

defined('YII_ENV') or define('YII_ENV', 'dev');

你可以把 YII_ENV 定义成以下任何一种值:

  • prod:生产环境。常量 YII_ENV_PROD 将被看作 true,这是 YII_ENV 的默认值。

  • dev:开发环境。常量 YII_ENV_DEV 将被看作 true。

  • test:测试环境。常量 YII_ENV_TEST 将被看作 true。

有了这些环境常量,你就可以根据当下应用运行环境的不同,进行差异化配置。 例如,应用可以包含下述代码只在开发环境中开启 调试工具。

$config = [...];if (YII_ENV_DEV) {
    // 根据 `dev` 环境进行的配置调整
    $config['bootstrap'][] = 'debug';
    $config['modules']['debug'] = 'yii\debug\Module';
}return $config;

关于配置的东西,大概就是这么多了。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

38

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

83

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

97

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

223

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

458

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

169

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

246

2026.03.03

C++高性能网络编程与Reactor模型实践
C++高性能网络编程与Reactor模型实践

本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

34

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Yii2中文手册
Yii2中文手册

共0课时 | 0.6万人学习

thinkphp基础介绍和yii2基础介绍
thinkphp基础介绍和yii2基础介绍

共10课时 | 2.3万人学习

Yii2框架基础视频教程
Yii2框架基础视频教程

共22课时 | 2.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号