SkillAgentSearch skills...

Configula

A simple PHP configuration reader that supports local config files and favors convention over configuration

Install / Use

/learn @caseyamcl/Configula
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Configula

Configula is a configuration library for PHP 8.2+ (older versions supported; see below).

[![Latest Version on Packagist][ico-version]][link-packagist] ![Software License][ico-license] [![Github Build][ico-ghbuild]][link-ghbuild] ![Code coverage][ico-coverage] [![PHPStan Level 5][ico-phpstan]][link-phpstan] [![Total Downloads][ico-downloads]][link-downloads]

Use this library when you want to load configuration from the filesystem, environment, and other sources. It implements your configuration values as an immutable object in PHP. It is a framework-independent tool, and can be easily used in any PHP application.

Features

  • Load configuration from a variety of sources:
    • Load values from .php, .ini, .json, and .yml configuration file types
    • Load values from the environment and .env files using a DotEnv library (vlucas or Symfony)
    • Write your own loaders to support other file types and sources
  • Cascade/deep merge values from multiple sources (e.g. array, files, environment, etc)
  • Optionally use in combination with Symfony Config Component to validate configuration values and/or cache them
  • Creates an immutable object to access configuration values in your application:
    • Array-access (read-only)
    • get(val), has(val), and hasValue(val) methods
    • Magic methods (__get(val), __isset(val), and __invoke(val))
    • Implements Traversable and Countable interfaces
  • Provides simple dot-based access to nested values (e.g. $config->get('application.sitename.prefix');)
  • Code quality standards: PSR-12, complete unit test coverage

Installation

composer require caseyamcl/configula

Upgrading?

Refer to UPGRADE.md for notes on upgrading from Version 2.x, 3.x, or 4.x to v5.

Need PHP v7.x, v5.x, or older Symfony compatibility?

Configula v5.x is compatible with PHP v8.2+.

  • If you need PHP 7.3+ compatibility, instruct Composer to use the 4.x version of this library: composer require caseyamcl/configula:^4.2
  • If you need PHP 7-7.2+ compatibility, instruct Composer to use the 3.x version of this library: composer require caseyamcl/configula:^3.2
  • If you need PHP 5.x support, you can use the 2.x version of this library (no longer maintained): composer require caseyamcl/configula:^2.4

Loading Configuration

You can use the Configula\ConfigFactory to load configuration from files, the environment, or other sources:

use Configula\ConfigFactory as Config;

// Load all .yml, .php, .json, and .ini files from directory (recursive)
// Supports '.local' and '.dist' modifiers to load config in correct order
$config = Config::loadPath('/path/to/config/files', ['optional' => 'defaults', ...]);

// Load all .yml, .php, .json, and .in files from directory (non-recursive)
// Supports '.local' and '.dist' modifiers to load config in correct order
$config = Config::loadSingleDirectory('/path/to/config/files', ['optional' => 'defaults', ...]);

// Load from array
$config = Config::fromArray(['some' => 'values']);

// Chain loaders -- performs deep merge
$config = Config::fromArray(['some' => 'values'])
    ->merge(Config::loadPath('/some/path'))
    ->merge(Config::loadEnv('MY_APP'));

Or, if you are loading an array, you can instantiate Configula\ConfigValues directly:

$config = new Configula\ConfigValues(['array' => 'values']);

Or, you can manually invoke any of the loaders in the Configula\Loader namespace:

$config = (new Configula\Loader\FileListLoader(['file-1.yml', 'file-2.json']))->load();

Accessing Values

The Configula\ConfigValues object provides several ways to access your configuration values:

// get method - throws exception if value does not exist
$config->get('some_value');

// get method with default - returns default if value does not exist
$config->get('some_value', 'default');

// find method - returns NULL if value does not exist
$config->find('some_value');
 
// has method - returns TRUE or FALSE
$config->has('some_value');
  
// hasValue method - returns TRUE if value exists and is not empty (NULL, [], "")
$config->hasValue('some_value');   

Accessing values using dot notation

Configula supports accessing values via dot-notation (e.g some.nested.var):

// Here is a nested array:
$values = [
    'debug' => true,
    'db' => [
        'platform' => 'mysql',
        'credentials' => [
            'username' => 'some',
            'password' => 'thing'
        ]
    ],
];

// Load it into Configula
$config = new \Configula\ConfigValues($values);

// Access top-level item
$values->get('debug'); // bool; TRUE

// Access nested item
$values->get('db.platform'); // string; 'mysql'

// Access deeply nested item
$values->get('db.credentials.username'); // string: 'some'

// Get item as array
$values->get('db'); // array ['platform' => 'mysql', 'credentials' => ...]

// has/hasValue work too
$values->has('db.credentials.key'); // false
$values->hasValue('db.credentials.key'); // false

Property-like access to your config settings via __get() and __isset():

// Access configuration values
$config = Config::loadPath('/path/to/config/files');

// Throws exception if value does not exist
$some_value = $config->some_key;

// Returns TRUE or FALSE
isset($config->some_key);

Iterator and count access to your config settings:

// Basic iteration
foreach ($config as $item => $value) {
    echo "<li>{$item} is {$value}</li>";
}

// Count
count($config); /* or */ $config->count();

Callable access to your config settings via __invoke():

// Throws exception if value does not exist
$value = $config('some_value'); 

// Returns default value if value does not exist
$value = $config('some_value', 'default');

Array access to your config settings:

// Throws exception if value does not exist
$some_value = $config['some_key'];    

// Returns TRUE or FALSE
$exists = isset($config['some_key']); 

// Not allowed; always throws exception (config is immutable)
$config['some_key'] = 'foobar'; // Configula\Exception\ConfigLogicException
unset($config['some_key']);     // Configula\Exception\ConfigLogicException

Merging Configuration

Since Configula\ConfigValues is an immutable object, you cannot mutate the configuration once it is set. However, you can merge values and get a new copy of the object using the merge or mergeValues methods:

use Configula\ConfigValues;

$config = new ConfigValues(['foo' => 'bar', 'baz' => 'biz']);

// Merge configuration using merge()
$newConfig = $config->merge(new ConfigValues(['baz' => 'buzz', 'cad' => 'cuzz']));

// For convenience, you can pass in an array using mergeValues()
$newConfig = $config->mergeValues(['baz' => 'buzz', 'cad' => ['some' => 'thing']]);

Configula performs a deep merge. Nested arrays are traversed, and the last value always takes precedence.

Note that Configula does not deep merge nested objects, only arrays.

Iterator and Count

The built-in ConfigValues::getIterator() and ConfigValues::count() methods flattens nested values when iterating or counting:

// Here is a nested array
$config = new Configula\ConfigValues([
    'debug' => true,
    'db' => [
        'platform' => 'mysql',
        'credentials' => [
            'username' => 'some',
            'password' => 'thing'
        ]
    ],
]);

// ---------------------

foreach ($config as $path => $value) {
    echo "\n" . $path . ": " . $value;
}

// Output:
//
// debug: 1
// db.platform: mysql
// db.credentials.username: some
// db.credentials.password: thing
// 

echo count($config);

// Output: 4

If you want to iterate only the top-level items in your configuration, you can use the getArrayCopy() method:

foreach ($config->getArrayCopy() as $path => $value) {
    echo "\n" . $path . ": " . $value;
}

// Output:
//
// debug: 1
// db: Array
//

Using the Folder Loader - Config Folder Layout

The folder loaders in Configula will load files with the following extensions (you can add your own custom loaders; see below):

  • php - Configula will look for an array called $config in this file.
  • json - Uses the built-in PHP json_decode() function
  • yaml or yml - Uses the Symfony YAML parser
  • ini - Uses the built-in PHP parse_ini_file() function

The ConfigFactory::loadPath($path) method will traverse directories in your configuration path recursively.

The ConfigFactory::loadSingleDirectory($path) method will load your configuration in a single directory non-recursively.

Local Configuration Files

In some cases, you may want to have local configuration files that override the default configuration files. There are two ways to do this:

  1. prefix the default configuration file extension with .dist (e.g. config.dist.yml), and name the local configuration file normally: config.yml
  2. name the default configuration file normally (e.g. config.yml) and prefix .local to the extension for the local configuration file: config.local.yml.

Either way will work, and you could even combine approaches if you want. The file iterator will always cascade merge files in this order:

  • FILENAME.dist.EXT
  • FILENAME.EXT
  • FILENAME.local.EXT

This is useful if you want to keep local configuration files out of revision control. Choose a paradigm, and simply add the following to your .gitignore

# If keeping .dist files...
[CONFIGDIR]/*
[!CONFIGDIR]/*.dist.*

# or, if ignoring .local files...
[CONFIGDIR]/*.local.*

Example

Consider the following directory layout...

/my/app/config
 ├config.php
 ├config.di
View on GitHub
GitHub Stars42
CategoryCustomer
Updated3mo ago
Forks8

Languages

PHP

Security Score

87/100

Audited on Dec 9, 2025

No findings