Configuration

The Configuration component in Zemit Core is a flexible and powerful tool for managing and accessing your application's configuration settings. It provides a default class with predefined values that can be customized to fit your needs, and also allows you to load environment variables from a .env file. The Configuration component is decoupled into multiple sections, making it easy to organize and manage your settings. With the Configuration component, you can easily control and adjust your application's configuration within the Zemit Core framework.

Good to know: Zemit is using vlucas Dotenv library to load and prepare environment variable from the .env file, please refer yourself to the official Dotenv documentation.

Basic .env examples

# Set Application Environment
APPLICATION_ENV=local

# Enable Debug
APP_DEBUG=true

# Enable Profiler
APP_PROFILER=true

# Enable Send Email
APP_SEND_EMAIL=true

# Use SMTP
MAILER_DRIVER=smtp
MAILER_SMTP_HOST=smtp.server.tld
MAILER_SMTP_PORT=465
MAILER_SMTP_ENCRYPTION=tls
MAILER_SMTP_USERNAME=username
MAILER_SMTP_PASSWORD="smtp_password"
MAILER_FROM_EMAIL=email@server.tld
MAILER_FROM_NAME="App Name"

# Enable APCU Cache
APP_CACHE=true
METADATA_DRIVER=apcu
CACHE_DRIVER=apcu

# Set Global Security Salt
SECURITY_SALT="my_app_salt"

# Set Master Database Configuration
DATABASE_HOST=localhost
DATABASE_DBNAME=database_name
DATABASE_USERNAME=database_username
DATABASE_PASSWORD="database_password"

# Add a new Slave Database
DATABASE_READONLY_ENABLE=true
DATABASE_READONLY_HOST=slave.db.server.tld

# Set Custom Authorization Header
IDENTITY_AUTHORIZATION_HEADER=X-Authorization

# Set Localisation
LOCALE_DEFAULT=fr
LOCALE_ALLOWED=fr,en,es
LOCALE_MODE=session_geoip
LOCALE_SESSION_KEY=my_app_local
TRANSLATE_LOCALE=fr_CA.utf8
TRANSLATE_DEFAULT_PATH=./app/Locales/

# Set Redis Server
REDIS_HOST=redis.server.tld
REDIS_PORT=6379

Advanced .env examples

Database Settings (Master & Slave)

Zemit currently only support MySQL/MariaDB database driver. There is no plan on adapting new databases adapters in the future. Since Phalcon does support many database adapters, nothing stops you from defining your own from your own configuration file.

Good to know: The Slave Database is only used as a read-only server and will automatically extend the master settings if they are not explicitly defined.

# Master Database Settings
DATABASE_ADAPTER=mysql
DATABASE_HOST=localhost
DATABASE_PORT=3306
DATABASE_DBNAME=database_name
DATABASE_USERNAME=database_username
DATABASE_PASSWORD="database_password"
DATABASE_CHARSET=utf8
DATABASE_PDO_EMULATE_PREPARES=false
DATABASE_PDO_STRINGIFY_FETCHES=false
MYSQL_ATTR_SSL_VERIFY_SERVER_CERT=true

Redis Settings

You can use the redis Driver for some components such as session, annotation, metadata and cache. By default, it will automatically retrieve the default Redis settings which is prefixed with REDIS_.

# Using Redis Server for session
SESSION_DRIVER=redis

# Using Redis Server for annotations
ANNOTATIONS_DRIVER=redis

# Using Redis Server for meta-data
METADATA_DRIVER=redis

# Using Redis Server for cache
CACHE_DRIVER=redis

# Default Redis Settings
REDIS_HOST=127.0.0.1
REDIS_PORT=6379

Good to know: It is also possible to overwrite the default redis configuration for each components if you would like to use distinct redis server per component.

# Extended Default Redis Settings
REDIS_DEFAULT_SERIALIZER=1
REDIS_LIFETIME=3600
REDIS_SERIALIZER=
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_INDEX=1
REDIS_AUTH=
REDIS_PERSISTENT=0
REDIS_SOCKET=

Creating your own Configuration

Phalcon: Because we are using Phalcon Config which extends the Collection class, you can refer yourself to the official Phalcon Configuration documentation as well as the Collection documentation for more information.

Create a new Config class which should look similar to this below:

// ./app/Bootstrap/Config.php
namespace App\Bootstrap;

use Zemit\Utils\Env;

class Config extends Zemit\Bootstrap\Config
{
    public function __construct(array $data = [], bool $insensitive = true)
    {
        parent::__construct([
            'app' => [
                // override whatever variable you want
                'version' => Env::get('APP_VERSION', '0.0.1')
                
                // add custom configs wherever you want
                'customKey' => Env::get('APP_CUSTOM_KEY', 'default-value')
                // ...
            ],
            
            // creating a new custom config
            'custom' => [
                'key' => Env::get('CUSTOM_KEY', 'default-value')
                // ...
            ],
        ], $insensitive);
        
        if (!empty($data)) {
            $this->merge(new PhalconConfig($data, $insensitive));
        }
    }
}

Once you have your custom Config class created, the bootstrap needs to be aware. To achieve this, we have multiple ways of doing that.

Method #1: Loading the custom Config Class from Bootstrap

You can refer yourself to the Bootstrap documentation method #1 (Using Bootstrap Variables). This is the preferred method if you want to avoid making a custom Service Provider for the Config Class

// ./app/Bootstrap.php
namespace App;

class Bootstrap extends \Zemit\Bootstrap
{
    public $config = \App\Bootstrap\Config::class;
}

Method #2: Loading using a custom Service Provider

If you wish to load the custom Config Class using from the service provider which is the recommended way. You will have to create your own Service Provider as shown below, and then load it from the Bootstrap using Bootstrap documentation method #2 (Using Bootstrap Service Providers).

// ./app/Provider/Config/ServiceProvider.php
namespace App\Provider\Config;

class ServiceProvider extends Zemit\Provider\AbstractServiceProvider
{
    protected $serviceName = 'config';
    
    /**
     * {@inheritdoc}
     *
     * @param DiInterface $di
     */
    public function register(DiInterface $di = null): void
    {
        // Set shared service in DI
        $di->setShared($this->getName(), function() use ($di) {
            
            /** @var Bootstrap $bootstrap */
            $bootstrap = $di->get('bootstrap');
            
            // Load your own custom Config 
            // Or the one which was provided from the $bootstrap->config variable
            $config = $bootstrap->config ?? new \App\Bootstrap\Config();
            if (is_string($config) && class_exists($config)) {
                $config = new $config();
            }
            
            // Set bootstrap mode into config
            $config->mode = $bootstrap->getMode();
            
            // Merge config with current environment
            $config->mergeEnvConfig();
            
            // Launch bootstrap prepare raw php configs
            $bootstrap->prepare->php($config->path('app'));
            
            // Set the config
            return $config;
        });
    }
}

Then you will have to map your own custom ServiceProvider to the Bootstrap like below:

// ./app/Bootstrap.php
namespace App;

class Bootstrap extends \Zemit\Bootstrap
{
    public $providers = [
        \Zemit\Provider\Config\ServiceProvider::class => \App\Provider\Config\ServiceProvider::class,
    ];
}

Last updated