Pular para o conteúdo principal

Advanced Features

Caching Configuration

The library supports caching of configuration values to improve performance, especially in production environments where configuration rarely changes.

Cache Modes

You can configure caching using either the fluent API or the constructor:

<?php
use ByJG\Config\CacheModeEnum;
use ByJG\Config\Environment;
use ByJG\Cache\Psr16\FileSystemCacheEngine;

$cache = new FileSystemCacheEngine('/path/to/cache');

// Fluent API (recommended)
$prod = Environment::create('prod')
->inheritFrom($dev)
->withCache($cache, CacheModeEnum::singleFile);

// Traditional constructor
$prod = new Environment(
'prod',
[$dev],
$cache,
false,
false,
CacheModeEnum::singleFile
);

There are two cache modes available:

ModeDescription
CacheModeEnum::multipleFilesEach configuration key is cached separately (default)
CacheModeEnum::singleFileAll configuration keys are cached as a single entry

When to use each cache mode:

  • Multiple Files: Better when you have many configuration entries that change independently
  • Single File: Better performance when loading the entire configuration at once and when changes are infrequent

Compatible Cache Implementations

You can use any PSR-16 compatible cache implementation. The library works well with:

Abstract and Final Environments

Environments can be marked as abstract or final to control inheritance:

<?php
use ByJG\Config\Environment;

// Fluent API (recommended)
// Abstract environment (cannot be loaded directly)
$baseConfig = Environment::create('base')
->setAsAbstract();

// Final environment (cannot be inherited from)
$secureConfig = Environment::create('secure')
->setAsFinal();

// Traditional constructor
$baseConfig = new Environment('base', [], null, true, false);
$secureConfig = new Environment('secure', [], null, false, true);

Abstract Environments

Abstract environments ($abstract = true) cannot be loaded directly but can be inherited by other environments. This is useful for creating base configurations that should never be used on their own.

aviso

If you try to build a container with an abstract environment, it will throw an exception.

Final Environments

Final environments ($final = true) cannot be inherited by other environments. This is useful for sensitive configurations that should not be extended.

aviso

If you try to create an environment that inherits from a final environment, it will throw an exception.

Extended Container Features

The Container class implements both PSR-11's ContainerInterface and the library's own ContainerInterfaceExtended, which provides additional methods:

<?php
// Standard PSR-11 methods
$value = $container->get('key');
$exists = $container->has('key');

// Extended methods
$rawValue = $container->raw('key'); // Get the raw value without processing
$keyStatus = $container->keyStatus('key'); // Check the status of a key

Key Status

The keyStatus() method returns a KeyStatusEnum value that provides information about the status of a key:

StatusDescription
KeyStatusEnum::NOT_FOUNDThe key does not exist in the container
KeyStatusEnum::STATICThe key exists and has a static value
KeyStatusEnum::IN_MEMORYThe key exists, is an instance, and is currently loaded in memory
KeyStatusEnum::WAS_USEDThe key exists, is an instance, was previously used but is no longer in memory
KeyStatusEnum::NOT_USEDThe key exists, is an instance, but has not been used yet

Error Handling

The library uses exceptions to handle error conditions:

ExceptionWhen it occurs
KeyNotFoundExceptionWhen a key is not found in the container
ContainerExceptionGeneral container errors
ConfigExceptionGeneral configuration errors
ConfigNotFoundExceptionWhen a configuration file is not found
DependencyInjectionExceptionWhen there's an error in dependency injection
RunTimeExceptionRuntime errors during container operations

Example of handling container exceptions:

<?php
use ByJG\Config\Exception\KeyNotFoundException;
use ByJG\Config\Exception\ContainerException;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Container\ContainerExceptionInterface;

try {
$value = $container->get('non_existent_key');
} catch (KeyNotFoundException $e) {
// Handle key not found
error_log("Configuration key not found: " . $e->getMessage());
} catch (NotFoundExceptionInterface $e) {
// Handle PSR-11 not found exception
error_log("PSR-11 key not found: " . $e->getMessage());
} catch (ContainerException | ContainerExceptionInterface $e) {
// Handle other container errors
error_log("Container error: " . $e->getMessage());
}

Performance Considerations

Caching

Using caching is strongly recommended for production environments. It significantly reduces the overhead of reading and parsing configuration files on each request.

Lazy Loading

The library uses lazy loading for configurations defined as closures and dependency injections. Values are only processed when they are requested, which improves performance.

Environment Inheritance

While environment inheritance is powerful, excessive inheritance chains can impact performance. Try to keep inheritance hierarchies shallow.

Singleton vs. Instance

Using toSingleton() for objects that are frequently accessed can improve performance by reusing the same instance.

Advanced Environment Setup Example

Here's a comprehensive example of setting up a complex environment configuration using the fluent API:

<?php
use ByJG\Config\Definition;
use ByJG\Config\Environment;
use ByJG\Config\CacheModeEnum;
use ByJG\Cache\Psr16\FileSystemCacheEngine;

// Create abstract base environment
$base = Environment::create('base')
->setAsAbstract();

// Development environment inherits from base
$dev = Environment::create('dev')
->inheritFrom($base);

// Staging environment with cache
$staging = Environment::create('staging')
->inheritFrom($dev)
->withCache(
new FileSystemCacheEngine('/tmp/cache/staging'),
CacheModeEnum::multipleFiles
);

// Production environment with optimized cache and marked as final
$prod = Environment::create('prod')
->inheritFrom($staging)
->withCache(
new FileSystemCacheEngine('/tmp/cache/prod'),
CacheModeEnum::singleFile
)
->setAsFinal();

// Create definition with all environments
$definition = (new Definition())
->withConfigVar('APP_ENV')
->addEnvironment($base)
->addEnvironment($dev)
->addEnvironment($staging)
->addEnvironment($prod);

// Build the container
$container = $definition->build();

Open source ByJG