Config Component


    Nearly all applications require configuration data for it to operate correctly. The configuration can contain parameters and initial settings for the application like location of log files, database connection values, services registered etc. The Phalcon\Config is designed to store this configuration data in an easy object oriented way. The component can be instantiated using a PHP array directly or read configuration files from various formats as described further down in the adapters section. extends the Phalcon\Collection object and thus inheriting its functionality.

    Factory

    We can easily create a or any of the supporting adapter classes Phalcon\Config\Adapter* by using the new keyword. However Phalcon offers the Phalcon\Config\ConfigFactory class, so that developers can easily instantiate config objects. Calling newInstance with the name, fileName and a parameters array will return the new config object.

    The allowed values for name, which correspond to a different adapter class are:

    • grouped
    • ini
    • json
    • php
    • yamlThe example below how to create a new PHP array based adapter:

    Given a PHP configuration file /app/storage/config.php

    1. <?php
    2. return [
    3. 'app' => [
    4. 'baseUri' => getenv('APP_BASE_URI'),
    5. 'env' => getenv('APP_ENV'),
    6. 'name' => getenv('APP_NAME'),
    7. 'timezone' => getenv('APP_TIMEZONE'),
    8. 'url' => getenv('APP_URL'),
    9. 'version' => getenv('VERSION'),
    10. 'time' => microtime(true),
    11. ],
    12. ];

    you can load it as follows:

    1. <?php
    2. use Phalcon\Config\ConfigFactory;
    3. $fileName = '/app/storage/config.php';
    4. $factory = new ConfigFactory();
    5. $config = $factory->newInstance('php', $fileName);

    As seen above, the third parameter for newInstance which is an array is not passed because it is not required. However, other adapter types use it, so you can supply it depending on the type of adapter you use. More information on what can be contained in the parameters array can be found in the adapters section.

    load

    The Config Factory also offers the load method, which accepts a string or an array as a parameter. If a string is passed, it is treated as the fileName of the file that we need to load. The extension of the file is what determines the adapter that will be used.

    1. <?php
    2. use Phalcon\Cache\CacheFactory;
    3. $fileName = '/app/storage/config.php';
    4. $factory = new ConfigFactory();
    5. $config = $factory->load($fileName);

    In the above example, the PHP adapter will be used (extension of the file) and the file will be loaded for you.

    If an array is passed, then the adapter element is required to specify what adapter will be created. Additionally filePath is required to specify where the file to load is located. More information on what can be contained in the array cam be found in the adapters section.

    Given an INI configuration file /app/storage/config.ini

    1. [config]
    2. adapter = ini
    3. filePath = PATH_DATA"storage/config"
    4. mode = 1

    the load function will create a config object:

    1. <?php
    2. use Phalcon\Cache\CacheFactory;
    3. $fileName = '/app/storage/config.ini';
    4. $factory = new ConfigFactory();
    5. $config = $factory->load($fileName);

    Exceptions

    Any exceptions thrown in the component will be of type Phalcon\Config\Exception. You can use this exception to selectively catch exceptions thrown only from this component.

    1. <?php
    2. use Phalcon\Config\Exception;
    3. use Phalcon\Mvc\Controller;
    4. class IndexController extends Controller
    5. {
    6. public function index()
    7. {
    8. try {
    9. // Get some configuration values
    10. $this->config->database->dbname;
    11. } catch (Exception $ex) {
    12. echo $ex->getMessage();
    13. }
    14. }
    15. }

    Native Array

    The Phalcon\Config component accepts a PHP array in the constructor and loads it up.

    1. <?php
    2. use Phalcon\Config;
    3. $config = new Config(
    4. [
    5. 'app' => [
    6. 'baseUri' => getenv('APP_BASE_URI'), // '/'
    7. 'env' => getenv('APP_ENV'), // 3
    8. 'name' => getenv('APP_NAME'), // 'PHALCON'
    9. 'timezone' => getenv('APP_TIMEZONE'), // 'UTC'
    10. 'url' => getenv('APP_URL'), // 'http://127.0.0.1',
    11. 'version' => getenv('VERSION'), // '0.1'
    12. 'time' => microtime(true), //
    13. ],
    14. ]
    15. );

    Magic

    You can retrieve the data from the object either using the key as a property (magic method):

    1. <?php
    2. echo $config->app->name; // PHALCON

    Path

    You can also use the path() method with a delimiter, to pass a string that will contain the keys separated by the delimiter:

    1. <?php
    2. echo $config->path('app.name'); // PHALCON

    path() also accepts a defaultValue which, if set, will be returned if the element is not found or is not set in the config object. The last parameter of path() is the delimiter to be used for splitting the passed string (path) which also denotes the nesting level.

    1. <?php
    2. echo $config->path('app-name', 'default', '-'); // PHALCON
    3. echo $config->path('app-unknown', 'default', '-'); // default

    You can also use the getPathDelimiter() and setPathDelimiter() methods to get or set the delimiter that the component will use. The delimiter parameter in the path() method can then be used as an override if you like, for a special case, while the default delimiter is set using the getter and setter. The default delimiter is ..

    You can also use functional programming in conjunction with path() to obtain configuration data:

    1. <?php
    2. use Phalcon\Di;
    3. use Phalcon\Config;
    4. /**
    5. * @return mixed|Config
    6. */
    7. function config() {
    8. $args = func_get_args();
    9. $config = Di::getDefault()->getShared('config');
    10. if (empty($args)) {
    11. return $config;
    12. }
    13. return call_user_func_array(
    14. [$config, 'path'],
    15. $args
    16. );
    17. }

    Get

    Finally you can use the get() method and chain it to traverse the nested objects:

    1. <?php
    2. echo $config
    3. ->get('app')
    4. ->get('name'); // PHALCON

    Since Phalcon\Config extends you can also pass a second parameter in the get() that will act as the default value returned, should the particular config element is not defined.

    Merge

    There are times that we might need to merge configuration data coming from two different config objects. For instance we might have one config object that contains our base/default settings, while a second config object loads options that are specific to the system the application is running on (i.e. test, development, production etc.). The system specific data can come from a .env file and loaded with a library.

    In the above scenario, we will need to merge the second configuration object with the first one. merge() allows us to do this, merging the two config objects recursively.

    1. <?php
    2. use Phalcon\Config;
    3. use josegonzalez\Dotenv\Loader;
    4. $baseConfig = new Config(
    5. [
    6. 'app' => [
    7. 'baseUri' => '/',
    8. 'env' => 3,
    9. 'name' => 'PHALCON',
    10. 'timezone' => 'UTC',
    11. 'url' => 'http://127.0.0.1',
    12. 'version' => '0.1',
    13. ],
    14. ]
    15. );
    16. // .env
    17. // APP_NAME='MYAPP'
    18. // APP_TIMEZONE='America/New_York'
    19. $loader = (new josegonzalez\Dotenv\Loader('/app/.env'))
    20. ->parse()
    21. ->toEnv()
    22. ;
    23. $envConfig= new Config(
    24. [
    25. 'app' => [
    26. 'env' => getenv('APP_ENV'), // 3
    27. 'name' => getenv('APP_NAME'), // 'MYAPP'
    28. 'timezone' => getenv('APP_TIMEZONE'), // 'America/New_York'
    29. 'url' => getenv('APP_URL'), // 'http://127.0.0.1',
    30. 'version' => getenv('VERSION'), // '0.1'
    31. 'time' => microtime(true), //
    32. ],
    33. 'logging' => true,
    34. ]
    35. );
    36. $baseConfig->merge($envConfig);
    37. echo $baseConfig
    38. ->get('app')
    39. ->get('name'); // MYAPP
    40. echo $baseConfig
    41. ->get('app')
    42. ->get('name'); // America/New_York
    43. echo $baseConfig
    44. ->get('app')
    45. ->get('time'); // 1562909409.6162

    The merged object will be:

    1. Phalcon\Config Object
    2. (
    3. [app] => Phalcon\Config Object
    4. (
    5. [baseUri] => '/',
    6. [env] => 3,
    7. [name] => 'MYAPP',
    8. [timezone] => 'America/New_York',
    9. [url] => 'http://127.0.0.1',
    10. [version] => '0.1',
    11. [time] => microtime(true),
    12. )
    13. [logging] => true
    14. )

    Using has() you can determine if a particular key exists in the collection.

    Set

    The component also supports set() which allows you to programmatically add or change loaded data.

    The object can be serialized and saved in a file or a cache service using the serialize() method. The reverse can be achieved using the unserialize method

    toArray / toJson

    If you need to get the object back as an array toArray() and toJson() are available.

    For additional information, you can check the Phalcon\Collection documentation.

    Other than the base component , which accepts a string (file name and path) or a native PHP array, there are several available adapters that can read different file types and load teh configuration from them.

    The available adapters are:

    Grouped

    The adapter allows you to create a Phalcon\Config object from multiple sources without having to create each object separately from its source and then merge them together. It accepts an array configuration with the necessary data as well as the defaultAdapter which is set to php by default.

    The first parameter of the constructor (arrayConfig) is a multi dimensional array which requires the following options

    • adapter - the adapter to be used
    • filePath - the path of the configuration file
    1. <?php
    2. use Phalcon\Config\Adapter\Grouped;
    3. $options = [
    4. [
    5. 'adapter' => 'php',
    6. 'filePath' => '/apps/storage/config.php',
    7. ],
    8. [
    9. 'adapter' => 'ini',
    10. 'filePath' => '/apps/storage/database.ini',
    11. 'mode' => INI_SCANNER_NORMAL,
    12. ],
    13. [
    14. 'adapter' => 'json',
    15. 'filePath' => '/apps/storage/override.json',
    16. ],
    17. ];
    18. $config = new Grouped($options);

    The keys set for each array element (representing one configuration file) mirror the constructor parameters of each adapter. More information regarding the parameters required or optional can be found in the relevant section describing each adapter.

    You can finally use array as the adapter value. If you choose to do so, you will need to use config as the second key, with values that represent the actual values of the configuration you want to load.

    1. <?php
    2. use Phalcon\Config\Adapter\Grouped;
    3. $options = [
    4. [
    5. 'adapter' => 'php',
    6. 'filePath' => '/apps/storage/config.php',
    7. ],
    8. [
    9. 'adapter' => 'array',
    10. 'config' => [
    11. 'app' => [
    12. 'baseUri' => '/',
    13. 'env' => 3,
    14. 'name' => 'PHALCON',
    15. 'timezone' => 'UTC',
    16. 'url' => 'http://127.0.0.1',
    17. 'version' => '0.1',
    18. ],
    19. ],
    20. ],
    21. ];
    22. $config = new Grouped($options);

    Ini

    Ini files are a common way to store configuration data. Phalcon\Config\Ini uses the optimized PHP function to read these files. Each section represents a top level element. Sub elements are split into nested collections if the keys have the . separator. By default the scanning method of the ini file is INI_SCANNER_RAW. It can however be overridden by passing a different mode in the constructor as the second parameter.

    1. [database]
    2. adapter = Mysql
    3. host = localhost
    4. username = scott
    5. password = cheetah
    6. dbname = test_db
    7. [config]
    8. adapter = ini
    9. filePath = PATH_DATA"storage/config"
    10. mode = 1
    11. [models]
    12. metadata.adapter = 'Memory'

    You can read the file as follows:

    1. <?php
    2. use Phalcon\Config\Adapter\Ini;
    3. $fileName = '/apps/storage/config.ini';
    4. $mode = INI_SCANNER_NORMAL;
    5. $config = new Ini($fileName, $mode);
    6. echo $config
    7. ->get('database')
    8. ->get('host'); // localhost
    9. echo $config
    10. ->get('models')
    11. ->get('metadata')
    12. ->get('adapter'); // Memory
    1. <?php
    2. use Phalcon\Cache\CacheFactory;
    3. $fileName = '/app/storage/config.ini';
    4. $factory = new ConfigFactory();
    5. $options = [
    6. 'adapter' => 'ini',
    7. 'filePath' => $fileName,
    8. 'mode' => INI_SCANNER_NORMAL,
    9. ];
    10. $config = $factory->load($options);

    or when using the newInstance() instead:

    1. <?php
    2. use Phalcon\Cache\CacheFactory;
    3. $fileName = '/app/storage/config.ini';
    4. $factory = new ConfigFactory();
    5. $params = [
    6. 'mode' => INI_SCANNER_NORMAL,
    7. ];
    8. $config = $factory->newinstance('ini', $fileName, $params);

    Json

    JSON is a very popular format, especially when transporting data from your application to the front end or when sending back responses from an API. It can also be used as a storage for configuration data. uses json_decode() internally to convert a JSON file to a PHP native array and parse it accordingly.

    1. {
    2. "database": {
    3. "adapter": "Mysql",
    4. "host": "localhost",
    5. "username": "scott",
    6. "password": "cheetah",
    7. "dbname": "test_db"
    8. },
    9. "models": {
    10. "metadata": {
    11. "adapter": "Memory"
    12. }
    13. }
    14. }

    You can read the file as follows:

    1. <?php
    2. use Phalcon\Config\Adapter\Json;
    3. $fileName = '/apps/storage/config.json';
    4. $config = new Json($fileName);
    5. echo $config
    6. ->get('database')
    7. echo $config
    8. ->get('models')
    9. ->get('metadata')
    10. ->get('adapter'); // Memory

    Whenever you want to use the Phalcon\Config\ConfigFactory component, you will just need to pass the name of the file.

    or when using the newInstance() instead:

    1. <?php
    2. use Phalcon\Cache\CacheFactory;
    3. $fileName = '/app/storage/config.json';
    4. $factory = new ConfigFactory();
    5. $config = $factory->newinstance('json', $fileName);

    The adapter reads a PHP file that returns an array and loads it in the Phalcon\Config object. You can store your configuration as a PHP array in a file and return the array back. The adapter will read it and parse it accordingly.

    1. <?php
    2. return [
    3. 'database' => [
    4. 'adapter' => 'Mysql',
    5. 'host' => 'localhost',
    6. 'username' => 'scott',
    7. 'password' => 'cheetah',
    8. 'dbname' => 'test_db',
    9. ],
    10. 'models' => [
    11. 'metadata' => [
    12. 'adapter' => 'Memory',
    13. ],
    14. ],
    15. ];

    You can read the file as follows:

    1. <?php
    2. use Phalcon\Config\Adapter\Php;
    3. $fileName = '/apps/storage/config.php';
    4. $config = new Php($fileName);
    5. echo $config
    6. ->get('database')
    7. ->get('host'); // localhost
    8. echo $config
    9. ->get('models')
    10. ->get('metadata')
    11. ->get('adapter'); // Memory

    Whenever you want to use the component, you will just need to pass the name of the file.

    1. <?php
    2. use Phalcon\Cache\CacheFactory;
    3. $fileName = '/app/storage/config.php';
    4. $factory = new ConfigFactory();
    5. $options = [
    6. 'adapter' => 'php',
    7. 'filePath' => $fileName,
    8. ];
    9. $config = $factory->load($options);

    or when using the newInstance() instead:

    1. <?php
    2. use Phalcon\Cache\CacheFactory;
    3. $fileName = '/app/storage/config.php';
    4. $factory = new ConfigFactory();
    5. $config = $factory->newinstance('php', $fileName);

    Yaml

    Requires PHP’s yaml extension to be present in the system

    Another common file format is YAML. requires the yaml PHP extension to be present in your system. It uses the PHP function yaml_parse_file to read these files. The adapter reads a yaml file supplied as the first parameter of the constructor, but also accepts a second parameter callbacks as an array. The callbacks supplies content handlers for YAML nodes. It is an associative array of tag => callable mappings.

    1. app:
    2. baseUri: /
    3. env: 3
    4. name: PHALCON
    5. timezone: UTC
    6. url: http://127.0.0.1
    7. version: 0.1
    8. time: 1562960897.712697
    9. models:
    10. metadata:
    11. adapter: Memory
    12. loggers:
    13. handlers:
    14. 0:
    15. name: stream
    16. 1:
    17. name: redis

    You can read the file as follows:

    1. <?php
    2. use Phalcon\Config\Adapter\Yaml;
    3. define("APPROOT", dirname(__DIR__));
    4. $fileName = '/apps/storage/config.yml';
    5. $callbacks = [
    6. "!approot" => function($value) {
    7. return APPROOT . $value;
    8. },
    9. ];
    10. $config = new Yaml($fileName, $callbacks);
    11. echo $config
    12. ->get('database')
    13. ->get('host'); // localhost
    14. echo $config
    15. ->get('models')
    16. ->get('metadata')
    17. ->get('adapter'); // Memory

    Whenever you want to use the component, you will can set the mode as a parameter.

    1. <?php
    2. use Phalcon\Cache\CacheFactory;
    3. define("APPROOT", dirname(__DIR__));
    4. $fileName = '/apps/storage/config.yml';
    5. $factory = new ConfigFactory();
    6. $options = [
    7. 'adapter' => 'yaml',
    8. 'filePath' => $fileName,
    9. 'callbacks' => [
    10. "!approot" => function($value) {
    11. return APPROOT . $value;
    12. },
    13. ],
    14. ];
    15. $config = $factory->load($options);

    or when using the newInstance() instead:

    1. <?php
    2. use Phalcon\Cache\CacheFactory;
    3. define("APPROOT", dirname(__DIR__));
    4. $fileName = '/app/storage/config.yaml';
    5. $factory = new ConfigFactory();
    6. $callbacks = [
    7. "!approot" => function($value) {
    8. return APPROOT . $value;
    9. },
    10. ];
    11. $config = $factory->newinstance('yaml', $fileName, $callbacks);

    Custom Adapters

    There are more adapters available for Config in the

    Dependency Injection

    As with most Phalcon components, you can store the object in your Phalcon\Di container. By doing so, you will be able to access your configuration object from controllers, models, views and any component that implements Injectable.

    An example of the registration of the service as well as accessing it is below:

    1. <?php
    2. use Phalcon\Di\FactoryDefault;
    3. use Phalcon\Config;
    4. // Create a container
    5. $container = new FactoryDefault();
    6. $container->set(
    7. 'config',
    8. function () {
    9. $configData = require 'config/config.php';
    10. return new Config($configData);
    11. }
    12. );
    1. <?php
    2. use Phalcon\Mvc\Controller;
    3. use Phalcon\Config;
    4. /**
    5. * @property Config $config
    6. */
    7. class MyController extends Controller
    8. {
    9. private function getDatabaseName()
    10. {
    11. return $this->config->database->dbname;
    12. }

    Also in your views (Volt syntax)