php runtime and server environment

Environment Variables

Environment variables are values provided to a process from outside the source code. PHP projects use them for settings that change between local, staging, CI, and production environments.

Typical examples are APP_ENV, database hostnames, cache URLs, queue names, feature flags, API keys, and secrets.

Reading Environment Variables

Use getenv() to read a value from the process environment.

PHP example
<?php

declare(strict_types=1);

$environment = getenv('APP_ENV');

echo 'Environment: ' . ($environment === false ? 'not set' : $environment) . PHP_EOL;

// Example:
// APP_ENV=local php env.php
//
// Prints:
// Environment: local

getenv() returns false when the variable is missing, so do not treat an empty string and missing value as the same thing unless your application rule says they are equivalent.

Setting Variables For One Command

On Linux and macOS:

APP_ENV=local php env.php

On Windows PowerShell:

$env:APP_ENV = "local"
php env.php

That is useful for local checks. Production values usually come from process managers, containers, platform configuration, secret managers, or deployment tooling.

Defaults And Required Values

Use defaults only when the application can safely run without the variable.

PHP example
<?php

declare(strict_types=1);

function envString(string $name, ?string $default = null): string
{
    $value = getenv($name);

    if ($value === false || $value === '') {
        if ($default !== null) {
            return $default;
        }

        throw new RuntimeException($name . ' is required.');
    }

    return $value;
}

echo envString('APP_ENV', 'production') . PHP_EOL;

For secrets and connection details, failing early is usually better than guessing.

Validating Values

Environment variables are strings. Parse and validate them before using them as booleans, integers, URLs, or lists.

PHP example
<?php

declare(strict_types=1);

function envBool(string $name, bool $default): bool
{
    $value = getenv($name);

    if ($value === false || $value === '') {
        return $default;
    }

    $parsed = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);

    if ($parsed === null) {
        throw new RuntimeException($name . ' must be a boolean value.');
    }

    return $parsed;
}

echo envBool('DEBUG_MODE', false) ? 'debug on' : 'debug off';
echo PHP_EOL;

// Example:
// DEBUG_MODE=true php debug.php
//
// Prints:
// debug on

Never assume "false" is falsey in PHP. It is a non-empty string, so (bool) "false" is true.

.env Files

Many frameworks use .env files for local development.

Example:

APP_ENV=local
DB_HOST=127.0.0.1
DB_DATABASE=app

Important habits:

  • commit .env.example, not real secrets
  • keep real .env files out of Git
  • do not rely on .env parsing unless the application or framework actually loads it
  • production may not use .env files at all

An environment variable is not magically available because it appears in a text file. Something must load it into the process.

CLI, FPM, Cron, And Workers Can Differ

Different processes can have different environments.

This can happen:

CLI APP_ENV=local
FPM APP_ENV=production
cron APP_ENV not set
worker APP_ENV=staging

When debugging missing values, check the process that actually runs the code:

  • terminal shell for CLI commands
  • PHP-FPM pool or service manager for web requests
  • cron entry for scheduled commands
  • Supervisor/systemd/container config for workers

Secrets

Environment variables are often used for secrets, but they are not automatically safe.

Avoid:

  • printing secrets in diagnostics
  • committing secrets to Git
  • dumping all environment variables in a public route
  • logging connection strings with passwords

If you need to prove a secret exists, print a safe marker instead:

PHP example
<?php

declare(strict_types=1);

$apiKey = getenv('API_KEY');

echo 'API_KEY: ' . ($apiKey === false || $apiKey === '' ? 'missing' : 'set') . PHP_EOL;

What You Should Be Able To Do

After this lesson, you should be able to read environment variables safely, distinguish missing values from empty strings, parse booleans, know how .env files relate to real process environment, and debug differences between CLI, web, cron, and worker environments.

For junior PHP work, this matters because configuration bugs often come from missing or misread environment variables. The professional habit is validating configuration at the boundary and avoiding leaked secrets.

Practice

Practice: Validate Runtime Configuration

Create a small PHP configuration loader that reads environment variables safely.

Task

Build a script that:

  • reads APP_ENV with a default of production
  • requires DATABASE_URL
  • reads DEBUG_MODE as a boolean with a default of false
  • prints safe status output without leaking the database URL

Use strict types. Keep example commands and output inside the PHP code block as comments.

Afterward, add a short note explaining why "false" must be parsed instead of cast to boolean.

Show solution

This solution parses configuration values before using them.

PHP example
<?php

declare(strict_types=1);

function envString(string $name, ?string $default = null): string
{
    $value = getenv($name);

    if ($value === false || $value === '') {
        if ($default !== null) {
            return $default;
        }

        throw new RuntimeException($name . ' is required.');
    }

    return $value;
}

function envBool(string $name, bool $default): bool
{
    $value = getenv($name);

    if ($value === false || $value === '') {
        return $default;
    }

    $parsed = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);

    if ($parsed === null) {
        throw new RuntimeException($name . ' must be a boolean value.');
    }

    return $parsed;
}

$appEnvironment = envString('APP_ENV', 'production');
$databaseUrl = envString('DATABASE_URL');
$debugMode = envBool('DEBUG_MODE', false);

echo 'APP_ENV: ' . $appEnvironment . PHP_EOL;
echo 'DATABASE_URL: ' . ($databaseUrl === '' ? 'missing' : 'set') . PHP_EOL;
echo 'DEBUG_MODE: ' . ($debugMode ? 'true' : 'false') . PHP_EOL;

// Example:
// APP_ENV=local DATABASE_URL=mysql://user:pass@localhost/app DEBUG_MODE=false php config.php
//
// Prints:
// APP_ENV: local
// DATABASE_URL: set
// DEBUG_MODE: false

The string "false" must be parsed because any non-empty string casts to true in PHP. filter_var() with FILTER_VALIDATE_BOOLEAN understands common boolean strings such as true, false, 1, 0, yes, and no.