При разработке часто приходится поддерживать сразу несколько окружений: development, staging. production итд., которые могут иметь довольно разные настройки. Самый простой пример это параметры соединения с базой данных, но иногда хочется изменить не только один параметр а целую секцию, например логирование или бэкенд для кеша. К тому же при разработки различных CMS иногда хочется вынести некоторые настройки на видное место, чтобы пользователю легче было их найти. Посмотрим как эти проблемы решается в PHPixie. Ну и конечно же все это работает без самого фреймворка и намного легче пакета symfony/config.
Параметры
Самое просто что мы можем сделать это создать несколько переменных которые потом использовать в конфиге, для этого создаем файл /assets/parameters.php:
<?php
// /assets/parameters.php
return [
'apiToken' => 'jdf73jdhgj',
// вложенные массивы тоже поддерживаются
'database' => [
'connection' => 'mysql:host=localhost;dbname=quickstart',
'user' => 'root',
'password' => 'secret'
]
];
Теперь мы можем использовать их в файлах конфигурации через %имя%, например:
<?php
// /assets/config/database.php
return [
'default' => [
'driver' => 'pdo',
'connection' => '%database.connection%',
'user' => '%database.user%',
'password' => '%database.password%'
]
];
Как результат мы отделяем сами переменные от того где они используются. Разумно затем добавить parameters.php в .gitignore и тогда кодом можно свободно делится на гитхабе.
Но что если нам нужно больше? Например добавить несколько роутов которые работают только у разработчиков и отключены в продакшене? Для этого нам понадобится оверлей.
Оверлеи
Допустим в одной из конфигураций мы хотим также подключить базу данных на MongoDB. Для этого создаем папку в с каким-то красивым именем, например local и добавляем туда локальные изменения:
<?php
// /assets/config/local/database.php
return [
// поскольку мы указываем другое имя соединения
// то уже определенное соединение 'default' не изменится.
// Оверлеи работают по принципу array_replace_recursive()
'mongo' => [
'driver' => 'mongo',
'database' => '%mongo.database%',
'user' => '%mongo.user%',
'password' => '%mongo.password%',
]
];
Если изменений мало можно даже не создавать папку а просто положить все в один файл:
<?php
// /assets/config/local.php
return [
'database' => [
// Еще раз подметим что в оверлей надо писать только
// изменения, и не надо копировать содержимое базового файла
// с соединением 'default'
'mongo' => [
'driver' => 'mongo',
'database' => '%mongo.database%',
'user' => '%mongo.user%',
'password' => '%mongo.password%',
]
]
];
Осталось только его включить, для этого в parameters.php добавляем одну строчку:
<?php
// /assets/parameters.php
return [
'configOverlay' => 'local',
// ...
];
Конечно же можно создать несколько таких оверлеев и переключатся между ними как угодно.
Как посмотреть результат?
Для отладки:
print_r($frameworkBuilder->configuration()->config()->get());
Использование без фреймворка
Весь функционал добавлен в базовые библиотеки Slice и Config. При создании конфигурации мы можем указать другую конфигурацию или Slice из которого будут грузится параметры:
$configBuilder = new \PHPixie\Config();
$parameterStorage = $configBuilder->file('parameters.php');
$rootDir = ...; // папка в которой лежит папка с конфигом (на уровень выше)
$dirName = 'config'; // имя папки с конфигом
$configuration = $configBuilder->directory($rootDir, $dirName, 'php', $parameterStorage);
С оверлеем еще проще, фактически можно слить два инстанса Slice или конфигурации в один. При этом ленивая подгрузка файлов продолжит нормально работать.
$sliceBuilder = new \PHPixie\Slice();
$configBuilder = new \PHPixie\Config();
$configuration = $configBuilder->file('config.php');
$overlay = $configBuilder->file('overlay.php');
$merged = $sliceBuilder->mergeData($configuration, $overlay);
Поделиться с друзьями
Комментарии (12)
andrewnester
19.05.2016 11:40+1по поводу организации конфигураций.
мне очень нравится подход, сделанный в Laravel — использование dotenv.
в корне есть .env файл, где содержится конфигурация специфичная для сервера.
либо мы можем установить эти переменные в переменные-окружения самого сервера.
по-моему, довольно просто и очевидное решениеjigpuzzled
19.05.2016 15:49поскольку parameters.php ПХП файл, можно просто сделать
return $_ENV;
и все =)andrewnester
19.05.2016 17:15ну в общем-то с первого взгляда это должно работать, согласен.
а Вы никак дефолтные значения для каких-то параметров не устанавливаете?
и если от CI у меня приходит название базы, имя и пароль в переменных окружения, мне надо что-то в духе писать?
return [ 'apiToken' => 'jdf73jdhgj', // вложенные массивы тоже поддерживаются 'database' => [ 'connection' => $_ENV['connection'], 'user' => $_ENV['user'], 'password' => $_ENV['password'] ] ];
shoomyst
Это всё интересно, но чем там в итоге закончилась история с накруткой скачиваний phpixie-библиотек с packagist? :)
jigpuzzled
Ооо нет, только давайте здесь не начинать )))
Если интересно, заходите к нам в чат, я там скоро буду: https://gitter.im/PHPixie/Hotline
Davert
Мне кажется, что эта история показала здравость РНР сообщества. Как вы знаете, сейчас на западе очень модно делать публичную травлю людей, через социальные сети за те или иные проступки. Не дай бог кому-то сморознуть шутку про расизм/гендерное неравенство, и чтобы рядом оказался человек без чувства юмора, но с популярным твиттер аккаутном… Всё, можешь попрощаться с работой, личной жизнью, привет угрозы и нервный срыв ) Подробнее здесь
Так вот к чему я. Когда начался тролинг на реддите — это было ок. Да, явно jigpuzzled там переусердствовал, но когда дело докатилось до PHP-FIG — там появился какой-то милый доброхот, который как раз действовал как типичный социальный троль. Ах, ты, сука, накручивал аккаунт, значит тебя надо исключить! На что члены PHP-FIG в большинстве своем отреагировали правильно — отказались участвовать в этой драме.
Массовая травля — это плохенько, понятненько?
Ну за скобками пока оставим дейтельность самого jigpuzzled но как бы в пиаре все средства хороши… Вопрос в эффективности этих средств, и как мне кажется, пока они работают против Пикси.
jigpuzzled
Если бы это все был я, то уж так бы не палился: нагенерить звезд на гитхабе и потом самому же твитнуть об этом как то не слишком умно
Davert
А завести акаунт на mail.ru, представиться чуваком из красноярска и написать душещипательное письмо о том как злостный менеджмент не позволяет юзать пикси? Тут мне кажется всё-таки явное палево.
Кроме того, если не ошибаюсь, на Хабре ты тоже не сразу признался, что ты и есть автор фреймворка.
Но вцелом всё это не важно. У тебя серьезные проблемы с репутацией фреймворка. Реддит-редитом, но когда это развалило FIG это уже стало серьезно ) А кроме того я пока не вижу чем он лучше других популярных фреймворков, учитывая, что там та же архитектура что в Yii и Laravel. Имхо, я бы рекомендовал на основе твоих компонтентов состряпать фреймворк другой архитектуры с более четкой специализацией. Ну и да… Никакой ентерпрайз не будет юзать пикси, хотя бы из-за названия. Иногда идти на поводу общественности и переименовывать фреймворк (я так уже делал).
jigpuzzled
Хз почему все так завелись за репутацию кстати.
На твиттере от меня никто не отписался, никто не зашел в чат и не сказал «все, завтра переписываю», даже звездочек на гитхабе на 2 больше стало. То есть, единственные кто бушует то те кто и так его не использовал ))) Это типа как феминистки против игр выступают, которые они бы и так не купили )))
С типом конечно история жесть, но напомню еще раз что я первый в треде FIG спалил что это не чисто.
Davert
И чо? Две звездочки — это в рамках статистической погрешности. Просто по сути ты очень хорошо умеешь себя пиарить, у тебя есть реальная возможность сделать действительно популярный проект. Но ты уперся рогом и двигаешь телегу, которая едет плохонько. Не знаю, может тебе и в кайф её толкать, но как по мне ты мог бы сделать гораздо больше.
Кроме того, что у тебя есть 5-20 человек которые активно юзают Пикси (надеюсь таки есть, но увы, мы их не видели в течении всей драмы), ты теряешь огормный потенциал всего сообщества. И вприцнипе проблема в том, что мы же не помидоры продаем — у Тейлора помидор хороший, у Фабьена хороший, у тебя тоже хороший. Но именно потому что фреймворк не помидор, у тебя его не купят даже если он хороший =) Будут брать те где есть сообщество, где есть поддержка, где есть реальные проекты.
Чтобы конкурировать тебе нужно как минимум предлагать что-то что не предлагают они. Selling points. И не только для разработчиков, а и для менеджеров