Библиотека laminas-config-aggregator
Рассмотрим библиотеку laminas-config-aggregator, как способ собрать конфигурацию php приложения
Что такое конфигурация приложения. Основные понятия
Основные понятия связанные с конфигурацией приложения:
- Развертывание приложения - это процесс использующий один код, но разные конфигурации приложения.
- Код - это один единый репозиторий, для всех развертываний приложения.
- Конфигурация приложения - это все то, что может меняться между развертываниями.
- Окружение - это настройки, которые меняются между развертываниями приложения. В каких-то случаях настройки окружения можно назвать развертываем приложения.
Если кратко, то конфигурация это такой большой массив с настройками базы данных, кешей, валидаторов, логгеров и других вещей.
Все критичные данных пароли, доступы к бд, нужно хранить в переменных окружения операционной системы, они и будут меняться между развертываниями приложения.
Чаще всего конфигурацию приложения группируют, по названию окружения:
development
production
test
staging
pre-production
Можно создать файл dependencies.php
и положить туда всю конфигурацию, но самым распространенным способом в разных фреймворках является наличие отдельного файла конфигурации для каждого из окружений, например:
1
2
3
4
configuration/
development.php
production.php
test.php
В каждом из которых будет массив конфигурации.
Недостатком такого подхода является дублирование параметров.
Чтобы этого избежать этого можно пойти следующим образом, обозначив отдельный файл для каждой отдельной конфигурации.
1
2
3
4
5
6
7
configuration/
db.global.php
logger.global.php
development.php
logger.development.php
production.php
test.php
Получается нагромождение файлов, со временем список файлов будет сложно читать и поддерживать.
Более удачный вариант на мой взгляд, разделить конфигурации в зависимости от окружений и модулей.
Модули - это просто группировка файлов по функционалу.
Например, разбив следующим образом:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/
Blog/
Configuration/
common/
logger.php
serializer.php
error.php
validator.php
db.php
development/
logger.php
db.php
twig.php
test/
twig.php
db.php
Configurations/
Authorization/
Получаем такую структуру, что у нас сначала идут модули, потом в них окружения и уже в них же конфигурация.
Теперь нужно собрать это все в один файл. Можно вручную рекурсивно собирать все файлы в один массив с помощью функции glob
.
Например, так:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
declare(strict_types=1);
$files = glob(__DIR__ . '/common/*.php');
$configs = array_map(
static function ($file) {
return require $file;
},
$files
);
return array_merge_recursive(...$configs);
Просто циклом пройдем по всем файлам и склеим все в один файл конфигурации.
Можно жить и так, но что делать с многомерными массивами, они будут некорректно перезаписывать одни и те же значения. Нужно что-то придумывать или воспользоваться специальными библиотеками для этого.
laminas-config-aggregator
Воспользуемся простой библиотекой laminas-config-aggregator
Она как раз нужна для объединения конфигурации из разных источников, будь это php
, xml
, yml
, ini
файлы.
Установка
Установка стандартная через composer
1
2
composer require laminas/laminas-config-aggregator
# На текущий момент, a это август 2024 актуальная версия 1.15.0
Использование
Итак, имеем структуру файлов:
1
2
3
4
5
└── Main
└── Configuration
├── db.global.php
├── main.production.php
└── test.global.php
Нам нужно склеить их в один.
1
2
3
4
5
6
7
8
9
use Laminas\ConfigAggregator\ConfigAggregator;
use Laminas\ConfigAggregator\PhpFileProvider;
// Подключаем все переданные файлы в ConfigAggregator правильным способом
$aggregator = new ConfigAggregator([
new PhpFileProvider(__DIR__. '/../src/Main/Configuration/*.global.php'),
]);
// Получаем итоговый массив
// Повторяющиеся ключи будут перезаписаны, что дает возможность удобно управлять конфигурацией например в зависимости от переменных окружения
var_dump($aggregator->getMergedConfig());
Рассмотрим другие варианты использования
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
use Laminas\ConfigAggregator\ConfigAggregator;
use Laminas\ConfigAggregator\PhpFileProvider;
// Класс конфигурации
class C
{
public function __invoke()
{
return ['db' => 999];
}
}
// Во всех массивах есть ключ db, в результирующем массиве будет последний со значением 999
$aggregator = new ConfigAggregator([
new PhpFileProvider(__DIR__. '/../src/Main/Configuration/*.production.php'),
new PhpFileProvider(__DIR__. '/../src/Main/Configuration/*.global.php'),
// Просто конфигурация из массива
function () {
return ['db' => 888];
},
// Конфигурация из класса
C::class
]);
var_dump($aggregator->getMergedConfig());
Применений этому можно найти массу.
Кэширование
Важной особенностью библиотеки является возможность кэширования конфигурации.
Имеет место если Конфиг очень большой и меняется нечасто.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
use Laminas\ConfigAggregator\ArrayProvider;
use Laminas\ConfigAggregator\ConfigAggregator;
use Laminas\ConfigAggregator\PhpFileProvider;
$aggregator = new ConfigAggregator([
// Укажем специальный ключ config_cache_enabled в true, тем самым скажем, что брать из кэша
new ArrayProvider([ConfigAggregator::ENABLE_CACHE => true]),
new PhpFileProvider(__DIR__. '/../src/Main/Configuration/*.production.php'),
new PhpFileProvider(__DIR__. '/../src/Main/Configuration/*.global.php'),
function () {
return ['db' => 888];
},
// Фаил куда сохранять конфигурацию
], 'var/config-cache.php');
var_dump($aggregator->getMergedConfig());
В результате получаем файл config-cache.php
вида:
1
2
3
4
5
6
7
8
9
10
11
<?php
/**
* This configuration cache file was generated by Laminas\ConfigAggregator\ConfigAggregator
* at 2024-08-25T16:02:08+00:00
*/
return [
'config_cache_enabled' => true,
'db' => 888,
'test' => 123
];
При последующих запросах, конфигурация будет браться из файла config-cache.php
.
Для того чтобы сбросить кэш, просто удалите файл.
Что получаем в итоге
Библиотека laminas/laminas-config-aggregator дает нам возможность:
- Удобно склеивать конфигурацию приложения с возможностью использовать регулярное выражение в пути.
- Помимо
php
массивов поддерживает и другие форматы конфигурации напримерxml
,yml
. - Сама библиотека имеет минимум зависимостей.
- Возможно кэшировать конфигурацию, для дальнейшего быстрого доступа к ней.
Как это использовать:
Для готового массива конфигурации можно найти массу применений.
Самое основное это передать его в контейнер внедрения зависимостей, для дальнейшего использования.
Например, можно склеивать массив с ошибками приложения, и выводить только последнюю ошибку.
Более подробно можно почитать в документации
Заключение
Важнее всего, чтобы работа с конфигурацией была удобной. Гибкость системы заключается в отсутствии зависимости между моделями данных, бизнес-логикой, поведением и местом хранения данных. Это позволяет разработчикам оставаться сосредоточенными на своих задачах, не отвлекаясь на технические ограничения.
Это первая статья из цикла статей построения приложений на php.
Остальные статьи:
- Библиотека laminas-config-aggregator - Текущая статья
- Контейнер внедрения зависимостей в php