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,这条都是满足的——无须担心

    eshop网上书店源码
    eshop网上书店源码

    适合初学的标准三层架构,采用ajax,页面布局div+css符合w3c,用vs自带的sqlserver,免配置sqlserver,使用方便,里面共有5个项目,点击最外层的.sln直接可运行。网站采用asp.net 用户角色配置(membership,UserRoles),用户角色、权限可在asp.net配置里修改,注册,登陆均采用asp.net登陆控件,网站根据用户角色自定义sitemap,基本上

    下载
  • 子类重载__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;

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

相关专题

更多
高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

43

2026.01.16

全民K歌得高分教程大全
全民K歌得高分教程大全

本专题整合了全民K歌得高分技巧汇总,阅读专题下面的文章了解更多详细内容。

84

2026.01.16

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

24

2026.01.16

java数据库连接教程大全
java数据库连接教程大全

本专题整合了java数据库连接相关教程,阅读专题下面的文章了解更多详细内容。

35

2026.01.15

Java音频处理教程汇总
Java音频处理教程汇总

本专题整合了java音频处理教程大全,阅读专题下面的文章了解更多详细内容。

16

2026.01.15

windows查看wifi密码教程大全
windows查看wifi密码教程大全

本专题整合了windows查看wifi密码教程大全,阅读专题下面的文章了解更多详细内容。

56

2026.01.15

浏览器缓存清理方法汇总
浏览器缓存清理方法汇总

本专题整合了浏览器缓存清理教程汇总,阅读专题下面的文章了解更多详细内容。

16

2026.01.15

ps图片相关教程汇总
ps图片相关教程汇总

本专题整合了ps图片设置相关教程合集,阅读专题下面的文章了解更多详细内容。

9

2026.01.15

ppt一键生成相关合集
ppt一键生成相关合集

本专题整合了ppt一键生成相关教程汇总,阅读专题下面的的文章了解更多详细内容。

26

2026.01.15

热门下载

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

精品课程

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

共0课时 | 0人学习

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

共10课时 | 2.2万人学习

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

共22课时 | 2.2万人学习

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

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