Charcoal Config
Configuration container for all things Charcoal.
This package provides easy hierarchical configuration container (for config storage and access).
Charcoal\Config
acts as a configuration registry / repository.
Main features
- Load data from ini, json or php files.
- Customizable separator access.
- Delegates (Chaining configurations).
- Array access.
- Implement Interop-Container.
- Provide Configurable Interface
Supported file formats
There are currently 3 supported file formats: ini
, json
and php
.
To load configuration from a file, simply use the add_file()
method. The file's extension will be used to determine how to load the file.
It is also possible to load a config file directly from the constructor, by passing a file string as the first argument.
$config = new \Charcoal\GenericConfig('../config/my-config.json');
JSON configuration
For the JSON file:
{
"example":{
"foo":"bar"
}
}
Loading this file into configuration would be:
$config = new \Charcoal\GenericConfig();
$config->add_file('./config/my-config.json');
// Output "bar"
echo $config['example/foo'];
INI configuration
For the INI file:
[example]
foo=bar
Loading this file into configuration would be:
$config = new \Charcoal\GenericConfig();
$config->add_file('./config/my-config.ini');
// Outputs "bar"
echo $config['exampe/foo'];
PHP configuration
The PHP configuration is loaded from an internal include
, therefore, the scope of $this
in the php file is the current Config instance.
For the PHP file:
<?php
$this['example'] = [
'foo'=>'bar'
];
Loading this file into configuration would be:
$config = new \Charcoal\GenericConfig();
$config->add_file('./config/my-config.php');
// Outputs "bar"
echo $config['example/foo'];
Separators
It is possible to fetch embedded array-ish values recursively in a single call with the help of separators.
The default separator is /
(it can be retrieved with separator()
) but it can be changed easily with set_separator()
.
👉 Separator must be a single character. An exception will be thrown if trying to callset_separator()
with a longer string.
How to use
$config = new \Charcoal\GenericConfig();
$config->set_separator('.'); // Default is "/"
$config->set_data([
'foo', [
'baz'=>example,
'bar'=>42
]
]);
// Ouput "42"
echo $config->get('foo.bar');
Delegates
It is possible to "chain" configuration containers with the help of delegates.
If one or more delegates are added to a class, they will be used as fallback when trying to fetch a key that isn't set in the config.
$config = new \Charcoal\Config\GenericConfig([
'foo' => 'baz'
]);
// Returns `false`
$config->has('bar');
// Throws exception
echo $config->get('bar');
$config2 = new \Charcoal\Config\GenericConfig([
'bar' => 42
]);
$config->add_delegate($config2);
// Returns 42
echo $config->get('bar');
Delegates can be set with:
-
set_delegates()
to set an array of delegates. -
add_delegate()
to add a config object at the end of the delegate list. -
prepend_delegate()
to add a config object at the beginning of the delegate list.
It is also possible to set delegates by passing them (as an array of ConfigInterface) to the constructor:
$config = new \Charcoal\Config\GenericConfig('../config/my-config.json', [$delegate1, $delegate2]);
👉 The order of the delegates is important. They are looked in the order they are added, so the first match is returned. Useprepend_delegate()
to add a config at the beginning of the stack (top priority).
Array Access
The config class implements the ArrayAccess
interface and therefore can be used with array style:
$config = new \Charcoal\Config\GenericConfig();
// Set value with array
$config['foobar'] = 42;
// Returns `42`
echo $config['foobar'];
// Returns `true`
isset($config['foobar']);
// Returns `false`
isset($config['invalid-key']);
// Invalidate the "foobar" config key
unset($config['foobar']);
Interoperability
The \Charcoal\Config
container implements the container-interop
interface.
See https://github.com/container-interop/container-interop.
This interface requires the get()
and has()
methods:
$config = new \Charcoal\Config\GenericConfig([
'foobar'=>42
]);
// Returns `true`
$config->has('foobar');
// Returns `false`
$config->has('invalid-key');
// Returns `42`
$config->get('foobar');
Configurable
Also provided in this package is a Configurable interface (\Charcoal\Config\ConfigrableInterface
) and its full implementation as a trait. \Charcoal\Config\ConfigurableTrait
.
Configurable (which could have been called "Config Aware") objects can have an associated config instance that can help defines various properties, states, or other.
The config object can be set with set_config()
and retrieve with config()
.
Implementation example:
use \Charcoal\Config\ConfigurableInterface;
use \Charcoal\Config\ConfigurableTrait;
use \Acme\Foo\FooConfig;
class Foo implements ConfigurableInterface
{
use ConfigurableTrait;
public function create_config(array $data = null)
{
$config = new FooConfig();
if ($data !== null) {
$config->set_data($data);
}
return $config;
}
}
The previous class could be use as such:
$foo = new Foo();
$foo->set_config([
'bar'=>[
'baz'=>42
]
]);
// echo 42
$foo_config = $foo->config();
echo $foo_config['bar/baz'];
Development
Coding Style
All Charcoal modules follow the same coding style and charcoal-core
is no exception. For PHP:
-
PSR-1, except for
- Method names MUST be declared in
snake_case
.
- Method names MUST be declared in
- PSR-2, except the PSR-1 requirement.
- PSR-4, autoloading is therefore provided by Composer
-
phpDocumentor
- Add DocBlocks for all classes, methods, and functions;
- For type-hinting, use
boolean
(instead ofbool
),integer
(instead ofint
),float
(instead ofdouble
orreal
); - Omit the
@return
tag if the method does not return anything.
- Naming conventions
- Use
snake_case
, notcamelCase
, for variable, option, parameter, argument, function, and method names; - Prefix abstract classes with
Abstract
; - Suffix interfaces with
Interface
; - Suffix traits with
Trait
; - Suffix exceptions with
Exception
; - For type-hinting, use
int
(instead ofinteger
) andbool
(instead ofboolean
); - For casting, use
int
(instead ofinteger
) and!!
(instead ofbool
orboolean
); - For arrays, use
[]
(instead ofarray()
).
- Use
Coding styles are enforced with grunt phpcs
(PHP Code Sniffer). The actual ruleset can be found in phpcs.xml
.
👉 To fix minor coding style problems, rungrunt phpcbf
(PHP Code Beautifier and Fixer). This tool uses the same ruleset as phpcs to automatically correct coding standard violations.
The main PHP structure follows the PSR-4 standard. Autoloading is therefore provided by Composer.
Authors
- Mathieu Ducharme mat@locomotive.ca
Changelog
0.2
Released on 2015-02-09
- Added the "delegates" feature.
- Setting value with a separator now tries to set as array.
- Implements the container-interop interface.
0.1.1
Released on 2015-12-02
- Removed the second argument for the constructor (currently unused).
- Clearer error message on invalid JSON files.
- Fix composer.json and the autoloader.
- Various internal changes (PSR2 compliancy, with psr1 exception).
0.1
Released on 2015-08-25
- Initial release of
charcoal-config
,