Переопределение файла конфигурации Yii - PullRequest
2 голосов
/ 31 октября 2011

У меня есть проект Yii с файлом конфигурации main.php и файлом конфигурации dev.php, который «наследует» от него.Файлы:

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'.Как я могу создать файл конфигурации, который наследуется от main.php, но может перезаписать опции при его слиянии?

Ответы [ 7 ]

3 голосов
/ 31 октября 2011

Насколько я вижу из исходного кода, он должен перезаписать ваш конфиг:

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 голос
/ 01 ноября 2011

Если в вашем проекте задействовано (или будет задействовано) более 1 разработчика, сервера или настроенного развертывания / тестирования, вам следует остерегаться проблем с VCS. Для нас мы решили импортировать отдельный файл db.php в config/main.php:

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

Файл db.php является копией (или символической ссылкой) либо db-test.php, либо db-deploy.php и игнорируется нашей VCS, в то время как различные файлы db - *. Php, созданные для отдельных пользователей, продолжают отслеживаться. по VCS:

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

Это позволяет отдельным разработчикам запускать систему на своем домашнем компьютере, подключенном к базам данных localhost, поддерживая связь развернутой системы с центральной базой данных.

0 голосов
/ 06 декабря 2012

Если вы используете 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();

Пропущенная часть находится вверху, где я определяю, являюсь ли я локальным или на сервере.

0 голосов
/ 04 ноября 2011

Моя проблема заключалась в том, что я загружал «index.php», когда хотел «index-dev.php». Мой редирект .htaccess не работал для «localhost /», но работал для «localhost / page».

Теперь я работаю, набрав localhost / index-dev.php

0 голосов
/ 01 ноября 2011

У меня есть 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')
);

просто запустите конфигурацию разработки или производства вместо основной конфигурации

0 голосов
/ 31 октября 2011

Как вы определяете, какой конфигурационный файл использовать? С оператором switch, с которым связан Стив?

Я использую оператор if в моем index.php, чтобы решить, какой конфигурационный файл использовать в зависимости от серверной среды (как упомянуто в статье, на которую ссылается Стив). Кажется, у меня нормально работает.

Также помните, что если вы запускаете консольное приложение, вы должны указать ему использовать правильный файл conig также в protected/yiic.php (как и в index.php).

Другая вещь, которая может происходить, это CMap::mergeArray, возможно, не сливается так, как вы хотите. Опять же, это работает для меня, но, возможно, когда массивы объединены, он перезаписывает неправильную строку конфигурации БД (выбирает неправильную)?

Один из способов исправить это - НЕ указывать кредиты БД в файле конфигурации main.php, , а просто иметь их в каждом наследуемом файле . Таким образом, вам потребуется файл наследования для каждой среды, и никакая среда не будет работать непосредственно из файла main.php. Таким образом, при объединении массивов у вас всегда будет правильная строка подключения к БД.

Удачи!

0 голосов
/ 31 октября 2011

Я извиняюсь, если Yii сильно изменился с тех пор, как я его протестировал, но, насколько я помню, вам нужно как-то обойти эту проблему.Вот ссылка, которая описывает несколько способов сделать это.Возможно, стоит проверить, не улучшилось ли что-либо.

Статья в блоге о конфигурации, зависящей от среды

Если вы работаете с разработкой, подготовкой и производственной средой, котораявсе они разделены и поддерживаются через git / svn / что-то еще, я считаю, что проще всего игнорировать определенные файлы конфигурации с каркасами, которые игнорируют настройки среды.Время от времени вам приходится вносить изменения в эти файлы вручную, но это не сложно, поскольку файлы конфигурации, как правило, остаются одинаковыми после создания приложения или веб-сайта.Таким образом, вы можете адаптировать свои настройки для вашей среды для лучшей отладки и тестирования на dev / staging, а также для повышения производительности и отсутствия отладки на производстве.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...