The preferred way to install this extension is through Composer.
Either run
php composer.phar require zelenin/zend-expressive-config "~2.1.0"
or add
"zelenin/zend-expressive-config": "~2.1.0"
to the require section of your composer.json
- PHP
- Yaml
- Arrays
- Collections
- Module config objects
<?php
use Zelenin\FooModule\Config\FooModuleConfig;
use Zelenin\Zend\Expressive\Config\ConfigManager;
use Zelenin\Zend\Expressive\Config\Provider\ArrayProvider;
use Zelenin\Zend\Expressive\Config\Provider\CacheProvider;
use Zelenin\Zend\Expressive\Config\Provider\PhpProvider;
use Zelenin\Zend\Expressive\Config\Provider\YamlProvider;
use Zelenin\Zend\Expressive\Config\Provider\AnnotationProvider;
$productionMode = true; // environment variable
$providers = [
new PhpProvider(__DIR__ . '/../config/autoload/*.global.php'),
new PhpProvider(__DIR__ . '/../config/autoload/*.local.php'),
new YamlProvider(__DIR__ . '/../config/autoload/*.global.yml'),
new YamlProvider(__DIR__ . '/../config/autoload/*.local.yml'),
new AnnotationProvider(__DIR__ . '/../src', __DIR__ . '/../data/cache/factories'),
new ArrayProvider(['foo' => 'bar']),
new FooModuleConfig(),
];
if ($productionMode) {
$providers = [new CacheProvider(__DIR__ . '/../data/cache/app-config.php', $providers)];
}
$manager = new ConfigManager($providers);
$config = $manager->getConfig();
Module config example:
namespace Zelenin\FooModule\Config;
use Zelenin\Zend\Expressive\Config\Provider\ModuleConfigProvider;
use Zelenin\Zend\Expressive\Config\Provider\CollectionProvider;
use Zelenin\Zend\Expressive\Config\Provider\PhpProvider;
use Zelenin\Zend\Expressive\Config\Provider\YamlProvider;
final class FooModuleConfig extends ModuleConfigProvider
{
/**
* @return array
*/
public function getConfig()
{
return [
'foo' => 'bar'
];
// or
return require_once 'fooModuleConfig.php';
// or
return (new CollectionProvider([
new PhpProvider(__DIR__ . '/../Resources/config/*.global.php')),
new PhpProvider(__DIR__ . '/../Resources/config/*.local.php')),
new YamlProvider(__DIR__ . '/../Resources/config/*.global.yml'))
new YamlProvider(__DIR__ . '/../Resources/config/*.local.yml'))
]))->getConfig();
}
}
You can resolve a variables like in the example below.
Config:
dependencies:
factories:
Zend\Stratigility\FinalHandler: 'Zend\Expressive\Container\TemplatedErrorHandlerFactory'
Zend\Expressive\Template\TemplateRendererInterface: 'Zend\Expressive\Twig\TwigRendererFactory'
twig:
cache_dir: '%rootDir%/data/cache/twig'
assets_url: '/'
assets_version: 1
globals: []
extensions: []
templates:
extension: 'html.twig'
paths:
application:
- '%moduleRootDir%/Resources/views'
Provider:
<?php
declare(strict_types=1);
namespace Zelenin\Application\Config;
use ArrayObject;
use Zelenin\Zend\Expressive\Config\Provider\CollectionProvider;
use Zelenin\Zend\Expressive\Config\Provider\ModuleConfigProvider;
use Zelenin\Zend\Expressive\Config\Provider\YamlProvider;
final class Provider extends ModuleConfigProvider
{
/**
* @return array
*/
public function getConfig(): array
{
return $this->resolveVariables(
(new CollectionProvider([
new YamlProvider(__DIR__ . '/../Resources/config/*.global.yml'),
new YamlProvider(__DIR__ . '/../Resources/config/*.local.yml'),
]))->getConfig()
);
}
/**
* @param array $config
*
* @return array
*/
private function resolveVariables(array $config): array
{
$variableRegistry = $this->getVariablesRegistry();
array_walk_recursive($config, function (&$value, $key) use ($variableRegistry) {
if (is_string($value)) {
if (preg_match('/%(.+)%/', $value, $matches)) {
$variable = $matches[1];
if (isset($variableRegistry[$variable])) {
$value = preg_replace('/%(.+)%/', $variableRegistry[$variable], $value);
}
}
}
});
return $config;
}
/**
* @return array
*/
private function getVariablesRegistry(): array
{
return [
'rootDir' => realpath(__DIR__ . '/../../..'),
'moduleRootDir' => realpath(__DIR__ . '/..'),
];
}
}
Supported annotations:
@Factory(id=Service::class)
@Invokable(id=InvokableService::class)
@Inject
@Middleware(path="/path")
@Route(path="/path", methods={"GET", "POST"}, name="route-name")
NB: @Middleware
and @Route
works only with programmatic_pipeline=false
Usage: see examples in Tests
Aleksandr Zelenin, e-mail: aleksandr@zelenin.me