vendor/bin/envless-env types reads the names, types and visibility of your variables, never their values, and writes a class with one static method per variable, typed by its declared type. A misspelt name or a bool used as a string then fails PHPStan, Psalm or your IDE instead of your deploy.
vendor/bin/envless-env types --output app/Support/EnvlessEnv.php --namespace 'App\Support'use App\Support\EnvlessEnv;
$databaseUrl = EnvlessEnv::DATABASE_URL();
$port = EnvlessEnv::PORT();
$debug = EnvlessEnv::DEBUG();
$browser = EnvlessEnv::client();It is the PHP counterpart of envless types, which writes envless-env.d.ts for TypeScript. The class costs nothing at runtime: each method is one call to Env::string(), Env::number() or Env::boolean(). Commit it, it holds no secrets.
What it writes
<?php
declare(strict_types=1);
namespace App\Support;
use Envless\Env\Env;
final class EnvlessEnv
{
public static function DATABASE_URL(): string
{
return Env::string('DATABASE_URL');
}
public static function PORT(): int|float
{
return Env::number('PORT');
}
public static function DEBUG(): bool
{
return Env::boolean('DEBUG');
}
/** @return array{DEBUG: bool} */
public static function client(): array
{
return [
'DEBUG' => Env::client()->boolean('DEBUG'),
];
}
}A string variable returns string, a boolean returns bool, and a number returns int|float, because a number reads back as an int when it is whole and a float when it is not. client() returns the variables marked client as a typed array shape, ready for json_encode() into a page.
Each method throws MissingVariableException when its variable is not set, like Env::get(). For a variable that may be absent, read it with Env::optional(). A variable named client or class, or one starting with two underscores, cannot be a method name, so the command skips it, says so on standard error, and it stays readable with Env::get().
Where the names come from
Under envless run, the command reads the manifest the CLI injected and makes no request, so your envless login session is all it needs:
envless run -- vendor/bin/envless-env types --output app/Support/EnvlessEnv.php --namespace 'App\Support'Outside it, the command fetches the metadata with the same machine credentials the loader uses: ENVLESS_TOKEN, with the project and environments from the flags, from ENVLESS_PROJECT and ENVLESS_ENV, or from .envless. No decryption key is needed. Every environment in .envless is read and merged in order, so a name that only exists in staging still gets a method, with the type of the first environment that declares it.
| Flag | Purpose |
|---|---|
--output PATH | The file to write, EnvlessEnv.php by default |
--class NAME | The class name, EnvlessEnv by default |
--namespace NAME | The namespace, none by default. Match it to where --output sits in your Composer autoload |
--project SLUG | The project, instead of ENVLESS_PROJECT or .envless |
--product SLUG | The product, when the project slug exists in more than one |
--env SLUGS | Comma separated environments, merged in order |
--check | Exit 1 when the file is missing or stale, and write nothing |
Keeping it current
Run it again whenever you add, rename or retype a variable. In CI, --check fails the job when the committed file no longer matches Envless:
envless run --env production -- vendor/bin/envless-env types --output app/Support/EnvlessEnv.php --namespace 'App\Support' --checkThe file is written in the PER coding style, so PHP-CS-Fixer and Laravel Pint leave it alone and --check stays green. Leave it out of hand edits: the next run replaces it.