PHP

PHP-FPM and plain PHP

Load Envless variables in any PHP app: the front controller, auto_prepend_file in php.ini or an FPM pool, passing credentials to PHP-FPM and Apache, the cache folder for www-data, and WordPress.

Without a framework, load once at the top of the script every request starts in, usually public/index.php, right after Composer's autoloader:

php
<?php

require __DIR__ . '/../vendor/autoload.php';

use Envless\Env\Env;

Env::load();

$pdo = new PDO(Env::string('DATABASE_DSN'), Env::string('DATABASE_USER'), Env::string('DATABASE_PASSWORD'));

Under PHP-FPM every request runs that line again. It is cheap: the ciphertext comes from the cache, so only the first request in each 15 minutes talks to the API, and each value is decrypted in microseconds with ENVLESS_KEY.

Without touching the code

vendor/envless/env/register.php loads when it is included, so PHP's auto_prepend_file can run it before every script. Set it in php.ini, in an FPM pool, or in a .user.ini beside your entry point:

ini
php_admin_value[auto_prepend_file] = /var/www/app/vendor/envless/env/register.php

That pool line covers every PHP file the pool serves. Use php_admin_value rather than php_value, so an application cannot switch it off.

Passing the credentials to PHP-FPM

PHP-FPM clears the environment of its workers by default, so variables exported in a shell, a systemd unit or a container never reach a request. Either keep the environment, or name each variable in the pool:

ini
clear_env = no
ini
env[ENVLESS_TOKEN] = $ENVLESS_TOKEN
env[ENVLESS_KEY] = $ENVLESS_KEY
env[ENVLESS_PROJECT] = api
env[ENVLESS_ENV] = production

The official php:*-fpm Docker images already set clear_env = no, so docker run -e ENVLESS_TOKEN=... -e ENVLESS_KEY=... works as it is. The project and environment can also come from a .envless file: the loader looks in the working directory and then in your Composer project root, so the file can sit next to composer.json while FPM runs public/index.php.

Apache

With mod_php, pass the credentials through from the server's environment, or set them in the virtual host:

apache
PassEnv ENVLESS_TOKEN ENVLESS_KEY
SetEnv ENVLESS_PROJECT api
SetEnv ENVLESS_ENV production

The cache folder for www-data

The cache lives under the home folder of the user PHP runs as. For www-data that is usually /var/www, which that user cannot write, so envless/env writes the ciphertext under the system temp folder instead, in envless-<uid>/cache with mode 0700, and only reads it back when the folder belongs to the same user. Nothing to configure. To keep the cache somewhere you choose, set HOME for the pool:

ini
env[HOME] = /var/lib/envless

When the API is down

A Node process loads at boot and keeps its values in memory through an outage. PHP-FPM loads on every request, so envless/env does the equivalent: when the cache has expired and the API cannot be reached, times out or answers 408, 429 or 5xx, it serves the last cached values and logs a warning through error_log(). A refused key or a missing environment is never covered, so revoking a machine key still stops the site.

WordPress

Load at the top of wp-config.php and define the constants from Envless:

php
<?php

require __DIR__ . '/vendor/autoload.php';

use Envless\Env\Env;

Env::load();

define('DB_NAME', Env::string('DB_NAME'));
define('DB_USER', Env::string('DB_USER'));
define('DB_PASSWORD', Env::string('DB_PASSWORD'));
define('DB_HOST', Env::string('DB_HOST'));
define('AUTH_KEY', Env::string('AUTH_KEY'));

Long-running PHP

RoadRunner, FrankenPHP in worker mode, Swoole and ReactPHP keep one PHP process alive across requests. Load once when the worker boots, before its request loop, and every request reads the memo. To pick up a change without restarting, call Env::load(revalidate: true) from a signal handler or a timer: see reloading.