Комментарии 21
Можно исходники привести в нормальный вид? А то я что-то потерялся тута :)
0
Дэжавю какое-то…
yiiframework.ru/doc/cookbook/ru/install.many.configs
yiiframework.ru/doc/cookbook/ru/install.many.configs
+1
В ZF это делается простым наследованием секций к примеру в ini-файлах, очень удобно… Можно ведь, как вариант, использовать Zend_Config в Yii проектах.
-2
У меня немного другое решение, к тому же оно более расширенное :)
Конфиг main.php содержит в себе все основные настройки, а в подпапке sites лежат все дополнительные настройки, спечифичные для каждого конкретного домена — в простейшем варианте это local, dev и production. У меня 1 проект висит на 5 доменах, так что это ещё и удобный multi-domain вариант, когда каждому домену нужно различающиеся настройки.
Прелесть CMap::mergeArray в том, что он обходит всё рекурсивно и добавляет (если элемента нету) или перекрывает (если элемент есть) элементы первого массива элементами из второго массива. Т.е. это позволяет мне держатьвсе настройки в main.php и переопределить отдельные настройки уже в специфическом для домена в его конфиге. Примерно вот так:
main.php
example.com.php — production site config
dev.example.com.php — dev config
Надеюсь общая концепция понятна :)
<?php
// Config base dir
$base = dirname(__FILE__).DIRECTORY_SEPARATOR.'protected'.DIRECTORY_SEPARATOR.
'config'.DIRECTORY_SEPARATOR;
// Get the domain
$domain = $_SERVER['SERVER_NAME'];
if (strpos($domain, 'www.') !== false) {
$domain = str_replace('www.', '', $domain);
}
if (!file_exists($base.'sites'.DIRECTORY_SEPARATOR.$domain.'.php')) {
$domain = 'dev.example.com';
}
$main = include($base.'main.php');
$domain_config = include($base.DIRECTORY_SEPARATOR.'sites'.DIRECTORY_SEPARATOR.$domain.'.php');
// Load the Yii framework
$yii=dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'yii'
.DIRECTORY_SEPARATOR.'framework'.DIRECTORY_SEPARATOR
.(defined('YII_DEBUG') ? 'yii.php' : 'yiilite.php');
require_once($yii);
// Merge configs
$config = CMap::mergeArray($main, $domain_config);
// Init the application
/** @var $app CWebApplication */
$app = Yii::createWebApplication($config);
unset($domain, $base, $yii, $config, $main, $domain_config);
Yii::import("ext.yiiext.components.zendAutoloader.EZendAutoloader", true);
// you are able to load custom code that is using Zend class naming convention
// with different prefix
EZendAutoloader::$prefixes = array('Zend', 'Custom');
Yii::registerAutoloader(array("EZendAutoloader", "loadClass"));
$app->run();
Конфиг main.php содержит в себе все основные настройки, а в подпапке sites лежат все дополнительные настройки, спечифичные для каждого конкретного домена — в простейшем варианте это local, dev и production. У меня 1 проект висит на 5 доменах, так что это ещё и удобный multi-domain вариант, когда каждому домену нужно различающиеся настройки.
Прелесть CMap::mergeArray в том, что он обходит всё рекурсивно и добавляет (если элемента нету) или перекрывает (если элемент есть) элементы первого массива элементами из второго массива. Т.е. это позволяет мне держатьвсе настройки в main.php и переопределить отдельные настройки уже в специфическом для домена в его конфиге. Примерно вот так:
main.php
<?php
return array(
'basePath' => dirname(__FILE__) . DIRECTORY_SEPARATOR . '..',
'defaultController' => 'site',
'components' => array(
'urlManager' => array(
'urlFormat' => 'path',
'showScriptName' => false,
'urlSuffix'=> '.html',
'rules' => array(
'<lang:\w{2}>/<controller:\w+>/<id:\d+>' => '<controller>/view',
'<lang:\w{2}>/<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<lang:\w{2}>/<controller:\w+>/<action:\w+>' => '<controller>/<action>',
'<lang:\w{2}>/<controller:\w+>' => '<controller>/index',
),
),
'db' => array(
'class' => 'system.db.CDbConnection',
'charset' => 'utf8',
'schemaCachingDuration'=>3600,
'emulatePrepare' => true,
),
),
'params' => array(
'mail' => array(
'smtp_from' => 'example@example.com',
'pass' => '12345',
'ip' => '192.168.0.1',
'port' => '25',
),
),
);
example.com.php — production site config
<?php
return array(
'components' => array(
'db' => array(
'connectionString' => 'mysql:host=mysql_host;dbname=project_db',
'username' => 'production',
'password' => 'production password',
),
),
);
dev.example.com.php — dev config
<?php
defined('YII_DEBUG') or define('YII_DEBUG',true);
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);
return array(
'components' => array(
'db' => array(
'connectionString' => 'mysql:host=localhost;dbname=project_db',
'username' => 'devuser',
'password' => 'dev password',
'enableProfiling' => true,
'enableParamLogging' => true,
'schemaCachingDuration' => 0,
),
),
'params' => array(
'mail' => array(
'smtp_from' => 'test@example.com',
'pass' => 'localtest',
'ip' => 'localhost',
'port' => '25',
),
),
);
Надеюсь общая концепция понятна :)
-1
А вам не кажется что по количеству буков данное решение является хумусом?
0
Непростому проекту непростые конфиги. Когда у вас на одной кодовой базе крутится 8 сайтов (и скажу далеко не визитки), отличающихся друг от друга дизайном, работающие с двумя базами — одной общей и по cms базе на каждый сайт — это ещё очень простое и элегантное решение на мой вкус. К тому же я же не выкладывал в примеры конфиги целиком — там гораздо больше опций, которые переопределяются для каждого сайта.
Это решение мне позволяет спокойно настраивать каждый сайт прямо на локальной машине, сохранять в репозиторий и выкладывать на рабочие сервера, при этом делать с моей локальной копией всё что хочу. И вообще каждый разработчик в комманде может спокойно иметь свой конфиг и спокойно переносить настройки между работой и домом.
В общем получается абсолютно прозрачная система.
Я всего лишь поделился своим решением. Использовать или нет — дело каждого лично. Не нравится — не пользуйтесь :)
Это решение мне позволяет спокойно настраивать каждый сайт прямо на локальной машине, сохранять в репозиторий и выкладывать на рабочие сервера, при этом делать с моей локальной копией всё что хочу. И вообще каждый разработчик в комманде может спокойно иметь свой конфиг и спокойно переносить настройки между работой и домом.
В общем получается абсолютно прозрачная система.
Я всего лишь поделился своим решением. Использовать или нет — дело каждого лично. Не нравится — не пользуйтесь :)
+1
А чем функция array_merge_recursive не угодила вместо самописной array_extends?
// конфиг в виде масива выглядит ужасно, ini или yml удобнее
// конфиг в виде масива выглядит ужасно, ini или yml удобнее
-1
Работа функции array_merge_recursive отличается от работы самописной функции array_extends, и она не подходила для данной задачи. Конфиг php не выглядит ужасно. Это обычный код. Зато в отличии от ini или yml в нем можно использовать php конструкции и объявлять переменные. Хотя в целом это дело вкуса как хранить настройки
0
У нас тоже стояла задача разделения конфигов в Yii, но мы её решили по-другому, — двумя ветками в git, серверной и девелоперской. После окончания работ в серверную ветку мержится девелоперская. Единожды разрешив конфликт мы больше с ним не сталкиваемся.
0
мы используем другой подход code.google.com/p/pha-yii-author/ — авторская конфигурация.
плюсы:
— каждый разработчик/инсталяция может имет собственный конфиг (со всеми штатными возможностями наследования)
— для подключения нет необходимости вносить изменения в код (index.php) — нужный конфиг подключается автоматически, стоит создать соответствующий пустой файл (соответствующая директория добавляется в игнор в системе контроля версий).
— поскольку конфиг у кажого свой разработчки может не бояться поломать общий файл, подключать в свем конфиге различные экспериментальные фичи
как ставить/подключать описано на форуме www.yiiframework.ru/forum/viewtopic.php?f=9&t=2479&p=15258
плюсы:
— каждый разработчик/инсталяция может имет собственный конфиг (со всеми штатными возможностями наследования)
— для подключения нет необходимости вносить изменения в код (index.php) — нужный конфиг подключается автоматически, стоит создать соответствующий пустой файл (соответствующая директория добавляется в игнор в системе контроля версий).
— поскольку конфиг у кажого свой разработчки может не бояться поломать общий файл, подключать в свем конфиге различные экспериментальные фичи
как ставить/подключать описано на форуме www.yiiframework.ru/forum/viewtopic.php?f=9&t=2479&p=15258
0
Идея хорошая, но зачем такие сложности? можно реализовать всё гораздо проще, без расширений.
В корне создаём файлик ".author" и в нем пишем ник автора.
В index.php добавляем:
ну и дальше как в вашем примере:
Авторские конфиги и «prodaction» мержим с «main», как описано в «рецептах»:
В корне создаём файлик ".author" и в нем пишем ник автора.
В index.php добавляем:
$webRoot = dirname(__FILE__);
$author = null;
$authorFile = $webRoot . '/.author';
if (is_file($authorFile)) {
$author = trim(file_get_contents($authorFile));
}
ну и дальше как в вашем примере:
if (!empty($author)) {
$config = $webRoot . '/protected/config/' . $author . '.php';
if (!file_exists($config)) {
$config = $webRoot . '/protected/config/main.php';
}
defined('YII_DEBUG') or define('YII_DEBUG',true);
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);
} else {
$config = $webRoot . '/protected/config/production.php';
}
Авторские конфиги и «prodaction» мержим с «main», как описано в «рецептах»:
<?php
return CMap::mergeArray(
require(dirname(__FILE__) . '/main.php'),
array(
'components'=>array(
'db' => array(
...
),
),
)
);
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Различные конфиги для режима production и режима отладки. Два в одном