在Yii的入口脚本中,配置是传给应用程序的唯一参数。正因为如此,配置文件在Yii里能完全决定程序的运行状态和行为。使用配置文件能减少程序中的硬编码,需要改动的时候只需修改配置文件,便于项目部署。相对于去代码里寻找并修改,这种方式无疑更为便捷和可维护。

Yii程序默认的配置文件位于protected/config文件夹下,main.php为web程序的主配置文件。大部分的配置是各环境共用的,所以main.php一般是放到代码库里的。但是数据库,memcache等配置项,在不同的开发机或者开发环境上经常性的会不同。如果项目是多人协同开发,在多个环境上部署,配置文件变更的可能性就很大。

如果把这些变更提交上去,其他人pull更新之后,又要依据本地环境修改一次。这种反复互相折腾的方法会很累的,因为这些本地的配置就不应该提交到代码库里。问题在于有部分人在提交之前从来不做diff,经常把本地的一些配置或者垃圾文件也都上传上去。这就需要解决这个问题,才能让多人一起愉快的协作。

推荐的解决办法是使用本地的配置文件,比如说命名为dev.php,我喜欢取名为local.php。这个文件不加入代码仓库里,并且这个文件的优先级是最高的。最高的意思是指:

  1. 即使其他配置文件里出现了相同的配置项,仍然以这个文件的配置为主
  2. 配置项是这个文件独有,配置项也是生效

有了这个文件的辅助,一些共用的配置还是放在main.php里面,而其他随着环境可能会改变的配置项则配置在local.php里。由于这个文件主要是写与main.php不同的配置,所以其内容应该是非常少的,因为重复main.php的内容是完全没有必要的。

Yii提供了 CMap::mergeArray 方法来合并配置,请不要使用php内置的array_merge或者array_merge_recursive函数来合并这些配置。合并完成之后作为配置传给cwebapplication。下面是一个使用示例的详细过程:

创建local.php

在protected/config文件夹下简历local.php,写入下面内容:

return CMap::mergeArray(
    require(dirname(__FILE__).'/main.php'),
    array(
        'modules' => array(
            'gii' => array(
               'class' => 'system.gii.GiiModule',
               'password' => '123456',
               'ipFilters' => array(
                   '127.0.0.1',
               ),
            ),
        ),
    )
);

在这里,我们针对本地开发环境启用gii组件,并且设置了用户名和密码。可以根据需要在这里自定义程序的运行参数信息。

相同的方法,如果项目配置文件庞大,可以新建多个配置文件,然后在main.php里面合成。这种方式对大项目来说是一种很好的维护方式。

修改index.php

有了local.php,我们应该告诉程序优先加载。将入口文件index.php修改如下:

< ?php
$cur_dir = dirname(__FILE__);

$yii = $cur_dir.'/../framework/yii.php';
require_once($yii);

$config_dir = $cur_dir.'/../protected/config/';
if (file_exists($config_dir.'/local.php')) {
    $config = $config_dir.'/local.php';
}
else {
    $config = $config_dir.'/main.php';
}

Yii::createWebApplication($config)->run();

首先我们查找local.php是否存在,如果存在则使用它,否则使用默认的main.php。通过这两个步骤,就实现了配置文件的分离,便于在不同的环境上协同工作。

顺带一提,也可以使用不同的入口文件办法做到这些事情。比如使用index-local.php加载本地配置,index.php加载线上配置。这种方法的一个不好之处就是url不统一,开发中不能使用统一的url,除非在web服务器上配置修改默认脚本文件名。

参考 1. yii 官网wiki