Envy part of Monolyth

Full documentationAPI referenceAll releases and notes

Latest release

0.4.1

Date: github

README.md

Flexible environment handler for PHP projects (including unit tests!)

When writing PHP projects that are more complicated than a two-page site, you're going to run into some real life problems:

Installation

Composer (recommended)

$ composer require monolyth/envy

Manual

  1. Download or clone the repository;
  2. Add /path/to/envy/src for the namespace Monolyth\\Envy\\ to your autoloader.

Usage

In a central place in your application (e.g. a bootstrapper that's always included) instantiate a "global" Environment object:

<?php

use Monolyth\Envy\Environment;

$env = new Environment('/path/to/my/configurations', function () {
    return 'production';
});

The first parameter is the location of the configuration file that defines your environments and their differences. Envy supports the following formats out of the box:

The top-level key is simply the name of the environment (define as many as you need), every second level are the settings. E.g., for JSON:

{
    "production": {
        "root-path": "/var/www"
    },
    "development": {
        "root-path": "/home/monomelodies/my-project"
    }
}

The second argument is a callable that should return the name of the environment you are currently operating in. How you decide that is up to you...

Optionally the Environment instance gets passed as an argument there, exposing some utility functions.

Once you're setup, simply request the values you need:

<?php

// $env configuration as described above...

include $env->root_path.'/some-file.php';

You can also set values after creation, e.g. the current language:

<?php

// Assuming $user is a logged in user...
$env->language = $user->language;

Note that this can also be done depending on the environment you determined in the constructor callable:

<?php

use Monolyth\Envy\Environment;

$env = new Environment('/path/to/config', function ($env) {
    if (check_for_cli()) {
        $env->someParameter = 'some value';
        return 'cli';
    } else {
        $env->someParameter = 'something else';
        return 'web';
    }
});

The callable used on construction may return multiple environments in an array. The found settings are then merged together (with the last defined taking precedence). This is extremely useful for keeping your config DRY and grouping settings depending on environment, e.g.:

{
    "web": {
        "serverName": "example.com"
    },
    "cli": {
        "serverName": "localhost"
    },
    "production": {
        "root-path": "/var/www"
    },
    "development": {
        "root-path": "/home/monomelodies/my-project"
    }
}

If the constructor callable returns ['web', 'production'] the Environment object will have the properties serverName and root_path set properly.

As a singleton

Global objects are evil, and some people don't use dependency injection. That's why Envy can also be called like a singleton:

<?php

use Envy\Environment;

Environment::setConfig('/path/to/config');
Environment::setEnvironment(function ($env) {
    // ...
});
$env = Environment::instance();

This is equivalent to the examples above.

Placeholders

Envy supports simple placeholders in environment variables:

{
    "test": {
        "somevar": "my name is <% user %>"
    }
}
<?php

$env = new Environment('/path/to/config', function ($env) {
    $env->user = get_current_user();
});

These replacements must be defined at the root level of your environment configuration to work.

Environment-conditional variables

You can specify variables that are only valid for combinations of environments, e.g. dev+programmer_bob versus dev+programmer-alice. Just use the plus sign in the environment key. These combined keys take precendence of single keys.

For XML-based config files (where + would be an illegal character), use the -AND- (in caps, this is important!) delimiter instead, e.g. <dev-AND-programmer-bob>...</dev-AND-programmer-bob>.