Charcoal Config

Configuration container for all things Charcoal.

Build Status

This package provides easy hierarchical configuration container (for config storage and access). Charcoal\Config acts as a configuration registry / repository.

Main features

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 call set_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:

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. Use prepend_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:

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, run grunt 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

Changelog

0.2

Released on 2015-02-09

0.1.1

Released on 2015-12-02

0.1

Released on 2015-08-25