-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
137 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,76 @@ | ||
# silex-config | ||
Simple multi-environment configuration for Silex with secret storage support | ||
## Simple multi-environment configuration for Pimple/Silex with secret storage support | ||
## Install | ||
``` | ||
composer install f3ath/silex-config | ||
composer install f3ath/pimple-config | ||
``` | ||
## Usage | ||
## Configuration structure | ||
### Environment-specific config | ||
A config is an `<environment_name>.php` file which returns an array: | ||
```php | ||
<?php | ||
// dev.php | ||
return [ | ||
'debug' => true, | ||
'foo' => [ | ||
'bar' => 'baz' | ||
] | ||
]; | ||
``` | ||
To reduce duplication, here is some sort of "inheritance": | ||
```php | ||
<?php | ||
// stage.php | ||
return array_replace_recursive(require __DIR__ . '/common.php', [ // inherit from common config | ||
'debug' => false, | ||
]); | ||
``` | ||
### Secret config | ||
It is a healthy practice to store sensitive data like passwords outside of the repository. The simplest implementation | ||
would be to store such files right on the server. These files may be edited directly, so they should not be php scripts, | ||
since there is a good chance to accidentally remove the `<?php` header and expose their content. A natural choice in | ||
this case is JSON. PimpleConfig supports a special `secret_json` key to include such files. | ||
```php | ||
<?php | ||
// prod.php | ||
return array_replace_recursive(require __DIR__ . '/common.php', [ // inherit from common config | ||
'secret_json' => '/etc/my_application/secret.json', | ||
'debug' => false, | ||
]); | ||
``` | ||
### Services | ||
Pimple services are configured in the set of files in the `services` directory. In your configuration you define: | ||
```php | ||
<?php | ||
// common.php | ||
return [ | ||
'services' => [ | ||
'application' => __DIR__ . '/services/application.php', | ||
'storage' => __DIR__ . '/services/storage.php', | ||
'controllers' => __DIR__ . '/services/controllers.php', | ||
], | ||
]; | ||
``` | ||
A service config is a php script which returns a special function: | ||
```php | ||
<?php | ||
// services/application.php | ||
return function (\Pimple\Container $container, array $config, string $env) { | ||
$container['hello'] = function () use ($config, $env) { | ||
// here you create and return a service in Pimple way | ||
}; | ||
}; | ||
``` | ||
## Register the configuration | ||
|
||
```php | ||
<?php | ||
$app = new \Silex\Application\Application(); | ||
$env = 'prod'; | ||
$path = '/path-to-config'; | ||
(new \F3\SilexConfig\Config($path))->configure($app, $env); | ||
$pimple = new \Pimple\Container(); | ||
$env_name = 'prod'; | ||
$config_root = '/path-to-config'; | ||
$pimple->register(new \F3\PimpleConfig\Config($config_root, $env_name)); | ||
``` | ||
|
||
For more examples see the [unit test](test/ConfigTest.php). | ||
For more examples see the [unit test](test/ConfigTest.php). | ||
|
||
### Contribution | ||
Please do! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,32 @@ | ||
{ | ||
"name": "f3ath/silex-config", | ||
"description": "Simple multi-environment configuration for Silex with secret storage support", | ||
"name": "f3ath/pimple-config", | ||
"description": "Simple multi-environment configuration for Pimple with secret storage support", | ||
"type": "library", | ||
"require-dev": { | ||
"silex/silex": "^2", | ||
"phpunit/phpunit": "^6.0", | ||
"squizlabs/php_codesniffer": "^2.8" | ||
}, | ||
"license": "MIT", | ||
"authors": [ | ||
{ | ||
"name": "Alexey Karapetov", | ||
"email": "[email protected]" | ||
} | ||
], | ||
"require": {}, | ||
"config": { | ||
"platform": { | ||
"php": "7" | ||
} | ||
}, | ||
"suggest": { | ||
"silex/silex": "Silex Framework" | ||
"require": { | ||
"pimple/pimple": "^3" | ||
}, | ||
"require-dev": { | ||
"phpunit/phpunit": "^6", | ||
"squizlabs/php_codesniffer": "^2.8" | ||
}, | ||
"autoload": { | ||
"psr-4": { | ||
"F3\\SilexConfig\\": "src/" | ||
"F3\\PimpleConfig\\": "src/" | ||
} | ||
}, | ||
"scripts": { | ||
"test": "vendor/bin/phpunit" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,58 +1,61 @@ | ||
<?php | ||
namespace F3\SilexConfig; | ||
namespace F3\PimpleConfig; | ||
|
||
use Silex\Application; | ||
use Pimple\Container; | ||
use Pimple\ServiceProviderInterface; | ||
|
||
class Config | ||
class Config implements ServiceProviderInterface | ||
{ | ||
const KEY_SERVICES = 'services'; | ||
const KEY_SECRET_JSON = 'secret_json'; | ||
private $dir; | ||
private $env; | ||
|
||
public function __construct(string $dir) | ||
public function __construct(string $config_root, string $environment_name) | ||
{ | ||
$this->dir = $dir; | ||
$this->dir = $config_root; | ||
$this->env = $environment_name; | ||
} | ||
|
||
public function configure(Application $app, string $env = 'prod') | ||
public function register(Container $pimple) | ||
{ | ||
$config = array_replace_recursive( | ||
$this->getDefaultConfig(), | ||
$this->getConfig($env) | ||
); | ||
if ($config[self::KEY_SECRET_JSON]) { | ||
$config = array_replace_recursive( | ||
$config, | ||
$this->getSecretConfig($config[self::KEY_SECRET_JSON]) | ||
); | ||
} | ||
array_map( | ||
function ($service) use ($app, $config, $env) { | ||
(require $service)($app, $config, $env); | ||
}, | ||
$config[self::KEY_SERVICES] | ||
); | ||
$config = $this->getConfig(); | ||
$config = $this->applySecretConfig($config); | ||
$this->configureServices($pimple, $config); | ||
} | ||
|
||
private function getConfig(string $env): array | ||
protected function getConfig(): array | ||
{ | ||
$file = "{$this->dir}/{$env}.php"; | ||
$file = "{$this->dir}/{$this->env}.php"; | ||
if (file_exists($file)) { | ||
return include $file; | ||
} | ||
throw new \InvalidArgumentException("Configuration not found for $env"); | ||
throw new \InvalidArgumentException("Configuration not found for {$this->env}"); | ||
} | ||
|
||
protected function applySecretConfig($config): array | ||
{ | ||
return array_replace_recursive( | ||
$config, | ||
$this->getSecretConfig($config) | ||
); | ||
} | ||
|
||
private function getDefaultConfig(): array | ||
protected function getSecretConfig(array $config): array | ||
{ | ||
return [ | ||
self::KEY_SERVICES => [], | ||
self::KEY_SECRET_JSON => null, | ||
]; | ||
$secret_json = $config['secret_json'] ?? null; | ||
if ($secret_json) { | ||
return json_decode(file_get_contents($secret_json), true); | ||
} | ||
return []; | ||
} | ||
|
||
private function getSecretConfig(string $file): array | ||
protected function configureServices(Container $container, array $config) | ||
{ | ||
return json_decode(file_get_contents($file), true); | ||
array_map( | ||
function ($service) use ($container, $config) { | ||
(require $service)($container, $config, $this->env); | ||
}, | ||
$config['services'] | ||
); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
<?php | ||
// Generic application settings | ||
return function (\Silex\Application $app, array $config, string $env) { | ||
$app['env'] = $env; | ||
$app['debug'] = $config['debug']; | ||
return function (\Pimple\Container $container, array $config, string $env) { | ||
$container['env'] = $env; | ||
$container['debug'] = $config['debug']; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
<?php | ||
// Configure the hello service | ||
return function (\Silex\Application $app, array $config) { | ||
$app['hello'] = function () use ($config) { | ||
return function (\Pimple\Container $container, array $config) { | ||
$container['hello'] = function () use ($config) { | ||
return "foo is {$config['foo']}, bar is {$config['bar']}, password is {$config['password']}"; | ||
}; | ||
}; |