Yii配置文件覆盖

时间:2011-10-31 04:48:21

标签: php yii

我有一个带有main.php配置文件和dev.php配置文件的Yii项目,该文件“继承”它。文件如下:

main.php:

<?php

// uncomment the following to define a path alias
// Yii::setPathOfAlias('local','path/to/local-folder');
// This is the main Web application configuration. Any writable
// CWebApplication properties can be configured here.
return array(
    'basePath' => dirname( __FILE__ ) . DIRECTORY_SEPARATOR . '..',
    'name' => 'FeedStreem',
    // preloading 'log' component
    'preload' => array( 'log' ),
    // autoloading model and component classes
    'import' => array(
        'application.models.*',
        'application.components.*',
        'application.controllers.*',
    ),
    // application components
    'components' => array(
        'db' => array(
            'connectionString' => 'mysql:host=remote.host.com;dbname=dbnamehere',
            'emulatePrepare' => true,
            'username' => 'username',
            'password' => 'password',
            'charset' => 'utf8',
            /*'enableProfiling' => true*/
        ),
        'user' => array(
            // enable cookie-based authentication
            'allowAutoLogin' => true,
        ),
        'authManager' => array(
            'class' => 'CDbAuthManager',
            'connectionID' => 'db'
        ),
        'urlManager' => array(
            // omitted
        ),
        'errorHandler' => array(
            // use 'site/error' action to display errors
            'errorAction' => 'site/error',
        ),
        'log' => array(
            'class' => 'CLogRouter',
            'routes' => array(
                array(
                    'class' => 'CFileLogRoute',
                    'levels' => 'trace, info, error, warning',
                ),
            ),
        ),
    ),
    // application-level parameters that can be accessed
    // using Yii::app()->params['paramName']
    'params' => array(
        // this is used in contact page
        'adminEmail' => 'webmaster@example.com',
    ),
);

dev.php:

<?php

return CMap::mergeArray(
    require(dirname( __FILE__ ) . '/main.php'),
    array(
        'modules' => array(
            'gii' => array(
                'class' => 'system.gii.GiiModule',
                'password' => 'SECRET',
                // If removed, Gii defaults to localhost only. Edit carefully to taste.
                'ipFilters' => array( '127.0.0.1', '::1' ),
            ),
        ),
        'components' => array(
            'db' => array(
                'connectionString' => 'mysql:host=localhost;dbname=dbname2',
                'emulatePrepare' => true,
                'username' => 'username2',
                'password' => 'password2',
                'charset' => 'utf8',
            ),
            'log' => array(
                'class' => 'CLogRouter',
                'routes' => array(
                    array(
                        'class' => 'CFileLogRoute',
                        'levels' => 'trace, info, error, warning',
                    ),
                    // uncomment the following to show log messages on web pages
                    array(
                        'class' => 'CWebLogRoute',
                    ),
                ),
            ),
        ),
    )
);

但是,当我在本地使用dev.php时,我收到以下错误:

Warning: PDO::__construct() [pdo.--construct]: [2002] No connection could be made because the target machine actively  (trying to connect via tcp://remote.host.com:3306) in C:\web_workspace\lib\yii\framework\db\CDbConnection.php on line 405

这告诉我dev.php没有覆盖'db'config选项。如何创建一个继承自main.php的配置文件,但在合并时可以覆盖选项?

7 个答案:

答案 0 :(得分:3)

据我所知,它应该覆盖你的配置:

public static function mergeArray($a,$b)
{
    foreach($b as $k=>$v)
    {
        if(is_integer($k))
            isset($a[$k]) ? $a[]=$v : $a[$k]=$v;
        else if(is_array($v) && isset($a[$k]) && is_array($a[$k]))
            $a[$k]=self::mergeArray($a[$k],$v);
        else
            $a[$k]=$v;
    }
    return $a;
}

来源:http://code.google.com/p/yii/source/browse/tags/1.1.8/framework/collections/CMap.php

官方文件也是这样说的:

  
    

如果每个数组都有一个具有相同字符串键值的元素,后者将覆盖前者(与array_merge_recursive不同)。

  

来源:http://www.yiiframework.com/doc/api/1.1/CMap#mergeArray-detail

尝试通过print_r结果数组来确定问题并查看它的内部结构。我认为问题出在这里。

答案 1 :(得分:1)

如果您的项目涉及(或将涉及)超过1个开发人员,服务器或自定义部署/测试,则必须注意VCS问题。对我们来说,我们发现最好在config/main.php中导入一个单独的db.php文件:

'db'=>require(dirname(__FILE__).'/db.php'),

db.php文件是db-test.phpdb-deploy.php的副本(或符号链接),我们的VCS会忽略它,而为各种db - * .php文件创建的个人用户继续被V​​CS跟踪:

bzr add protected/config/db-*.php
bzr ignore protected/config/db.php

这允许各个开发人员在连接到localhost数据库的家庭计算机上运行系统,同时维护已部署系统与中央数据库的链接。

答案 2 :(得分:0)

如果Yii从我测试过后发展得很多,我很抱歉,但我记得,你需要解决这个问题。这是一个链接,概述了这样做的几种方法。值得一看,看看情况是否有所改善。

Blog article on environment dependent configuration

如果您使用dev,staging和production环境,这些环境都是独立的,并通过git / svn /其他方式进行维护,我发现使用忽略环境设置的框架忽略某些配置文件是最容易的。您必须有时在这些文件中手动进行更改,但这并不困难,因为配置文件在建立应用程序或网站后往往保持相似。通过这种方式,您可以针对您的环境定制设置,以便更好地调试和测试开发/暂存,以及更好的性能和生产调试。

答案 3 :(得分:0)

您如何确定要使用的配置文件?使用像Steve链接的switch语句?

我在index.php中使用if语句来决定根据服务器环境使用哪个配置文件(如Steve链接的文章中所述)。它似乎对我很好。

另外请记住,如果您正在运行控制台应用程序,则需要告诉它在protected/yiic.php中使用正确的conig文件(就像在index.php中一样)。

可能发生的另一件事是CMap::mergeArray可能不会像你想要的那样合并。同样,它适用于我,但也许当数组合并时,它会覆盖错误的数据库配置字符串(它选择了错误的数据库)?

解决这个问题的一种方法是在main.php配置文件中没有DB信用,只需在每个继承文件中使用它们。因此,您需要为每个环境提供一个继承文件,并且不会直接从main.php文件运行任何环境。这样,当合并数组时,您将始终拥有正确的数据库连接字符串。

祝你好运!

答案 4 :(得分:0)

我有2个配置文件(开发和生产)。也许你可以尝试我的配置。

<强> main.php

return array(
    'name' => 'My Application',
    'language' => 'id',
    'charset' => 'utf-8',
    'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
    // gii module
    'modules' => array(
        'gii' => array(
            'class' => 'system.gii.GiiModule',
            'password' => 'admin'
        ),
    ),

    // autoloading model and component classes
    'import'=>array(
        'application.models.*',
        'application.components.*',
    ),

    // preloading 'log' component
    'preload' => array('log'),
    'defaultController' => 'site',
    // application components
    'components' => array(
        'user' => array(
            // enable cookie-based authentication
            'allowAutoLogin' => true,
            'loginUrl' => array('user/login'),
        ),
        'errorHandler' => array(
            // use 'site/error' action to display errors
            'errorAction' => 'site/error',
        ),
    ),

    // application-level parameters that can be accessed
    // using Yii::app()->params['paramName']
    'params'=>require('params.php'),
);

您可以自定义如何显示开发和生产服务器的错误日志

development.php //您可以自定义为开发和生产导入的包

return CMap::mergeArray(
    array(
        'components'=>array(
            'db'=>array(
                'connectionString' => 'mysql:host=localhost;dbname=mydb',
                'emulatePrepare' => true,
                'username' => 'root',
                'password' => '',
                'charset' => 'utf8',
                'tablePrefix' => '',
            ),
            'log' => array(
                'class' => 'CLogRouter',
                'routes' => array(
                    array(
                        'class' => 'CFileLogRoute',
                        'levels' => 'error, warning',
                    ),
                    array(
                        'class' => 'CWebLogRoute',
                    ),
                    array(
                        'class' => 'CDbLogRoute',
                        'levels' => 'trace, info, warning, error',
                        'connectionID' => 'db',
                        'autoCreateLogTable' => true,
                    ),
                ),
            ),
        ),
    ),
    require('main.php')
);

<强> production.php

return CMap::mergeArray(
    array(
        'components'=>array(
            'db'=>array(
                'connectionString' => 'mysql:host=myserver.com;dbname=mydb',
                'emulatePrepare' => true,
                'username' => 'root',
                'password' => 'mypassword',
                'charset' => 'utf8',
                'tablePrefix' => '',
            ),
            'log' => array(
                'class' => 'CLogRouter',
                'routes' => array(
                    array(
                        'class' => 'CFileLogRoute',
                        'levels' => 'error, warning',
                    ),
                    array(
                        'class' => 'CDbLogRoute',
                        'levels' => 'trace, info, warning, error',
                        'connectionID' => 'db',
                        'autoCreateLogTable' => true,
                    ),
                ),
            ),
        ),
    ),
    require('main.php')
);

只运行开发或生产配置而不是主配置

答案 5 :(得分:0)

我的问题是当我想要“index-dev.php”时,我实际上正在加载“index.php”。 我的.htaccess重定向不适用于“localhost /”,但它适用于“localhost / page”。

我现在通过输入“localhost / index-dev.php

来实现它

答案 6 :(得分:0)

如果您正在使用Yii,您还可以使用CMap :: mergeArray函数来执行已接受答案的较长版本。

我的索引文件的最后一部分如下所示:

$configMain = require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'protected'.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'main.php');
$configServer = require_once( dirname( __FILE__ ).DIRECTORY_SEPARATOR.'protected'.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'main' . $env . '.php' );

require_once($yii);

$config = CMap::mergeArray( $configMain, $configServer );
// Set Path alias for all javascript scripts
Yii::setPathOfAlias('js', dirname($_SERVER['SCRIPT_NAME']).DIRECTORY_SEPARATOR."js/");
Yii::createWebApplication($config)->run();

遗漏的部分位于顶部,我确定我是本地还是服务器。