Допустим, у нас есть приложение на базе advanced app с директориями common и backend. Каждая директория включает конфиги - общие (common) и специфические (backend) для приложения. Также конфиги приложения делятся на глобальные (main.php в терминологии yii2, main.global.php в моей терминологии) и локальные (main-local.php/main.local.php). Первые конфиги содержат настройки независящие от окружения, вторые же - перезаписывают глобальные настройки настройками локальными (например включая дебаг на машине разработчика).
Стандартная практика: мерджить глобальные конфиги с конфигами локальными. Неудобство: приходится в ручную проверять наличие конфигов вслед за ошибками require, при создании нового конфига вручную его мерджить в другой конфиг и прочее, с чем вы уже сталкивались. Плюс в большом приложении количество конфигов быстро растет (либо же растет кол-во строк в них) - за каскадом конфигов становится трудно следить.
По мотивам знакомства с Zend Expressive написал небольшой менджер, работающий с любой библиотекой имеющий конфигурирование массивами (точнее принимающей на вход конфиг в виде массива, т.к. написав свой провайдер можем иметь конфиги в каком угодно формате, например yml/xml/ini).
Код:
Код: Выделить всё
use yii\web\Application;
use Zelenin\Zend\Expressive\Config\Manager\Config;
use Zelenin\Zend\Expressive\Config\Provider\CacheProvider;
use Zelenin\Zend\Expressive\Config\Provider\PhpProvider;
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require(__DIR__ . '/../../vendor/autoload.php');
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');
$manager = new Config(
[
new PhpProvider(__DIR__ . '/../../common/config/{{,*.}global,{,*.}local}.php'),
new PhpProvider(__DIR__ . '/../config/{{,*.}global,{,*.}local}.php'),
],
YII_DEBUG ? null : new CacheProvider(__DIR__ . '/../runtime/app-config.php')
);
(new Application($manager->getConfig()))->run();
PhpProvider в качестве аргумента принимает паттерн для функции glob. Что делает паттерн из примера: загружает по порядку global.php, *.global.php, local.php, *.local.php и все это дело мерджит.
Также можно добавить конфиг в виде массива - new ArrayProvider(['components' => ['class' => 'MyNewComponent']]),, или создать конфиг для быстрого подключения своего модуля:
Код: Выделить всё
new MyModuleConfigProvider()
Код: Выделить всё
namespace MyModule;
use Zelenin\Zend\Expressive\Config\Provider\ModuleConfigProvider;
final class MyModuleConfigProvider extends ModuleConfigProvider
{
/**
* @return array
*/
public function getConfig()
{
return [
'modules' => [
'myModule' => [
'class' => 'MyModule\Module',
'foo' => 'bar'
]
]
];
// or
return require_once 'fooModuleConfig.php';
// or
return (new PhpProvider(__DIR__ . '/config/*.php'))->getConfig();
}
}
UPD: ну да, забыл https://github.com/zelenin/zend-expressive-config