Skip to content

PHP

To use varlock with PHP, install the standalone binary and run your app under varlock run — it loads and validates your env, then injects it into the process.

Add @generatePhpEnv to your schema to generate a small, self-contained class — a readonly Env with typed promoted properties, a static load() that parses the injected __VARLOCK_ENV blob, and a SENSITIVE_KEYS constant.

.env.schema
# @generatePhpEnv(path=Env.php)

The file is regenerated automatically on varlock load and varlock run, or explicitly with varlock codegen. Requires PHP 8.1+ (readonly promoted properties).

Call load() once, then read fields off the object — required fields are the plain type, optional ones are nullable (?type):

<?php
require_once 'Env.php'; // require_once — a second require would fatal
$env = Env::load(); // call once, hold or inject $env
$port = $env->DB_PORT; // ?int
$debug = $env->DEBUG; // ?bool
// SENSITIVE_KEYS is available for your own redaction
foreach (Env::SENSITIVE_KEYS as $key) { /* ... */ }
Terminal window
varlock run -- php main.php

load() throws a clear error if __VARLOCK_ENV is missing (e.g. you forgot varlock run) or if a required key is absent.

Every load() call re-parses the blob. To avoid reloading, bind the loaded instance wherever your app keeps shared services — e.g. your DI container:

bootstrap.php
$container->instance(Env::class, Env::load()); // resolve Env anywhere, type-hinted

No container? A tiny static holder works:

final class Config {
public static Env $env;
}
Config::$env = Env::load();
// elsewhere: Config::$env->DB_PORT (?int)

By default the class is a global final class Env loaded via require_once. For Composer projects, set namespace= and/or class= on the decorator and register the file via classmap autoload instead:

.env.schema
# @generatePhpEnv(path=src/Env.php, namespace="App\Config", class=AppEnv)
composer.json
{ "autoload": { "classmap": ["src/Env.php"] } }

Under PHP-FPM, make sure the pool passes __VARLOCK_ENV through (clear_env = no).