Pull to refresh

Comments 23

Слияние конфигурации в Yii — это, по моим тестам (профайлинг xdebug-ом), очень, очень медленно. mergeArray почему-то страшно тупит — чуть ли не 20% времени скрипта.

Для себя я решил проще — шаблоны конфигурации, слияние и запись в файл (один-единственный). На продакшене — делаем что-то а-ля ./yiic makeConfig production, на девеле — соответственно меняем параметр.
Про эту особенность я не слышал. Спасибо за наводку. Буду иметь ввиду. Что касается приведенного примера, то можно для продакшена использовать файл без слияния, а остальным переопределять именно конфигурацию продакшена. Т.е. в моем примере основная конфигурация будет не в main.php а production.php. Конфиги типа devel.php будут переопределять уже конфигурацию production.php. По идее это должно решить проблему с тормозами и сохранить простоту. Как думаете?
я всегда ложу конфиг в кеш, незачем его каждый раз вычислять
Зачем здесь вообще CMap::mergeArray()? Есть же array_replace_recursive().
Ну какбэ merge и replace — разные вещи ;).
Спасибо, я знаю. Я имел ввиду, то что CMap::mergeArray() делает то же, что и array_replace_recursive(), по крайней мере CMap::mergeArray() является реплейсем а не мержем.

Выполните код:
$mainConfig = array(
    'components' => array(
        'db' => array(
            'connectionString' => 'mysql:host=prodaction_host;dbname=prodaction_dbname',
            'emulatePrepare'   => true,
            'username'         => 'prodaction_username',
            'password'         => 'prodaction_password',
            'charset'          => 'utf8'
        ),
    ),
);

$devConfig = array(
    'components' => array(
        'db' => array(
            'connectionString' => 'mysql:host=dev_host;dbname=dev_dbname',
            'username'         => 'dev_username',
            'password'         => 'dev_password'
        ),
    ),
);

var_dump(array_replace_recursive($mainConfig, $devConfig));
var_dump(CMap::mergeArray($mainConfig, $devConfig));
var_dump(array_replace_recursive($mainConfig, $devConfig) === CMap::mergeArray($mainConfig, $devConfig));
Все верно.
Просто привычка от ZF использовать встроенные функции, даже когда есть альтернативы. Такая же как и использовать Yii::app()->request->getPost() вместо $_POST. Других причин нет.
Зачем эта функция нужна в Yii и как сюда попала лучше спросить у автора фреймворка. Может он посчитал что она быстрее будет работать?! А может просто решил "пусть будет" )). В ZF принято всегда пользоваться функциями фреймворка а не нативного языка. В Yii таких рекомендаций нет, и каждый ложит что угодно куда угодно и использует что угодно где угодно.
Да, я конечно, не против использовования CMap::mergeArray(), но вот почему я не делаю этого в конфиге:
я тоже разделяю конфига на один базовый и конкретные (prodaction, dev, test и т.д.) и затем мержу их. Плюс в конфигах я так же определяю константы, таки как:

define('YII_DEBUG', true);
define('YII_TRACE_LEVEL', 3);
define('YII_ENABLE_ERROR_HANDLER', true);
define('YII_ENABLE_EXCEPTION_HANDLER', true); 


Но так как в yii.php уже определены эти константы и подключение его раньше моего конфига вызовет конфликт, а CMap::mergeArray() использовать без yii.php не получиться (можно конечно по отдельности подключить файлы «CMap.php», «CComponent.php», но по моему это не вариант) — я использую array_replace_recursive().

P.S. Почему я не определяю константы в index.php? — потому, что их значения тоже зависят от окружения (prodaction, dev, test).
Да, верно. Тоже хороший вариант.
Зачем эта функция нужна в Yii и как сюда попала лучше спросить у автора фреймворка.

Думаю причина в том, что array_replace_recursive появился только в PHP 5.3, а Yii 1.* поддерживает PHP 5.1
И array_replace_recursive перезаписывает ключи с индексами типа integer, в отличии от CMap::mergeArray
я придерживаюсь следующих критериев при разделения конфигов:
1. Привязка конфига к имени сервера
2. По умолчанию использовать продакшн конфиг
3. Должна быть возможность определить несколько доменов (таже с помошью регулярок) для одного конфига
4. Должна быть возможность выбрать конфиг с помошью параметра в запросе (только для разрешенных айпи)
UFO landed and left these words here
Тут речь не о том что бы вносить изменения в зависимые от версии конфиги. Речь о том что когда работаешь над проектом его приходится выкладывать на продакшен сервер. И даже минимально но приходится менять настройки БД. Иногда обновление конфига становится проблемной темой.
Помимо настроек БД там могут прописываться десяток путей к различным директориям и другие всевозможные персональные конфигурации.
А еще у проекта бывает не один разработчик а команда. Несколько программеров, тестеры, фокус группы… Часто каждая группа использует свой сервер. В этих условиях конфиги лучше иметь каждому свой, но позволить наследовать основной — эталонный.
Подходы которые я видел ранее с указанием имени или IP сервера менее гибкие. Хотя бы по той причине что имена у серверов (как ни крути) но могут пересекаться, не говоря уже о куче localhost`ов и 127.0.0.1`ов. А в описанном мною способе, который кстати используется в Symphony и ZF, достаточно определить значение переменной APPLICATION_ENV для сайта и программа уже сама подтянет соответствующий конфиг переопределив нужные параметры у эталона. И не нужно ни регепсов, ни сравнений имени, ни if`ов и switch`ей… Даже не нужно применять хитроумные шаблоны проектирования и это гораздо проще чем использовать разные конфигурации в ветках на git. Кстати для меня лично загадка почему подобный подход ранее не был описан ну или очень далеко спрятан.
как по мне — это самое очевидное и простое решение, которое я отчасти перенес даже в проекты на ExtJS.
никогда не понимал всех этих хитрых манипуляций с регулярками, айпишками и именами хоста. проекту, зачастую, вовсе не интересно на каком хосте он работает. а если проект написан так, что любой из разработчиков может поднять его копию на своей локальной машине под произвольным хостом, то тут и вовсе кромешный ад начинается.
Пробывал делать как предлагает автор где то год назад. Но постала проблема из консолю, там нет константы окружения сервера. Как автор решил эту проблему.

Можно использовать системные переменные или отдельный файл с именем окружения.
С переменной окружения системы это самый очевидный вариант. Все просто и довольно гибко. Как говорит принцип Лезвия Оккама — «Самое простое — самое верное» :)
не было возможности менять конфиг окружения, выкрутился расширением. схему себе оставил такую — большинство параметров (достаточное их количество) хранится в main.php, конфигурации переключаются на уровне проекта наличием файлика (см. вики расширения)
Все решается просто.
Во первых нужно учитывать что для CLI Yii имеет свой конфиг, а значит что бы разбить конфигурацию для вызова из консоли требуется привести ее в соответствующий вид.
Во вторых переменную окружения можно добивать в систему и она таким же образом будет видна в Yii.

В Linux переменная окружения в систему добавляется так "export APPLICATION_ENV=devel;". В Windows это сделать не сложнее. Соответственно быстрый вызов скрипта из консоли Linux может выглядеть так "export APPLICATION_ENV=devel; ./yiic test". Главное не забываете что для того что бы это все заработало вам нужно изменить соответствующим образом файл /protected/yiic.php вашего скрипта.

Все делается по аналогии со статьей, только переменная окружения добавляется не в Apache а в саму систему. Если кому интересно могу напечатать отдельный очерк по этой теме.
я же написал — не было возможности менять конфиг окружения. конфиг консольный части Yii в моем варианте находится все в том же main.php, вместо с конфигом от веб-приложения. зачем мне пересказывать статью, если я и так безболезненно решил вопрос?
Сори, ошибся. Это чуть выше нужно было.
Sign up to leave a comment.

Articles