Skip to content

PHP Tutorial Practical PHP Development

Environment Variables

Lesson 316 of 369 2 min read By Deepak Paswan Updated Oct 5, 2026

Environment variables hold settings outside your code, set by the server, hosting panel, Docker or a .env file. They are the standard place for secrets and for values that change between environments.

You met the basics in $_ENV and getenv(). Here is how to use them in a project.

Read a variable

index.php
PHP
<?php
putenv("APP_ENV=local");   // normally set outside PHP

echo getenv("APP_ENV") . "\n";
echo getenv("MISSING") === false ? "missing" : "set";
Output
OUTPUT
local
missing

A .env file for local development

On your own computer, typing variables into the server settings is awkward. A .env file lists them as KEY=value lines.

Text
PLAIN
APP_ENV=local
APP_DEBUG=true
DB_HOST=127.0.0.1
DB_NAME=shop
DB_USER=root
DB_PASS=

Rules for the file:

  • It is never committed to Git. Add .env to .gitignore.
  • You commit a .env.example with the names and harmless sample values, so others know what to set.
  • It lives outside the public web folder.

A tiny loader

index.php
PHP
<?php
function parseEnv(string $contents): array
{
    $vars = [];

    foreach (preg_split('/\R/', $contents) as $line) {
        $line = trim($line);

        if ($line === "" || str_starts_with($line, "#") || !str_contains($line, "=")) {
            continue;
        }

        [$key, $value] = explode("=", $line, 2);
        $vars[trim($key)] = trim($value, " \t\"'");
    }

    return $vars;
}

$env = parseEnv("# database\nDB_HOST=127.0.0.1\nDB_NAME=\"shop\"\n\nAPP_DEBUG=true");

print_r($env);
Output
OUTPUT
Array
(
    [DB_HOST] => 127.0.0.1
    [DB_NAME] => shop
    [APP_DEBUG] => true
)

For real projects, use the vlucas/phpdotenv package. It handles quotes, comments, variable references and required variables:

terminal
BASH
composer require vlucas/phpdotenv
index.php
PHP
<?php
require __DIR__ . "/vendor/autoload.php";

$dotenv = Dotenv\Dotenv::createImmutable(dirname(__DIR__));
$dotenv->safeLoad();
$dotenv->required(["DB_HOST", "DB_NAME"]);

Types: everything is a string

Environment values are always strings. "false" is a non-empty string, which is truthy.

index.php
PHP
<?php
function envBool(string $value, bool $default = false): bool
{
    $result = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);

    return $result ?? $default;
}

var_dump(envBool("true"));
var_dump(envBool("false"));
var_dump(envBool("0"));
var_dump(envBool("nonsense", true));
Output
OUTPUT
bool(true)
bool(false)
bool(false)
bool(true)

A typed Env helper

index.php
PHP
<?php
final class Env
{
    public function __construct(private array $values) {}

    public function string(string $key, string $default = ""): string
    {
        return (string) ($this->values[$key] ?? $default);
    }

    public function int(string $key, int $default = 0): int
    {
        return filter_var($this->values[$key] ?? null, FILTER_VALIDATE_INT) ?: $default;
    }

    public function bool(string $key, bool $default = false): bool
    {
        return filter_var($this->values[$key] ?? null, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ?? $default;
    }
}

$env = new Env(["DB_PORT" => "3307", "APP_DEBUG" => "false", "DB_HOST" => "db.internal"]);

echo $env->string("DB_HOST") . ":" . $env->int("DB_PORT", 3306) . " debug=" . var_export($env->bool("APP_DEBUG", true), true);
Output
OUTPUT
db.internal:3307 debug=false

Where the values come from in production

  • The hosting control panel (many hosts have an “environment variables” screen).
  • Apache SetEnv, PHP-FPM env[...], or php.ini.
  • Docker (-e, env_file) and CI/CD secrets.
  • A .env file on the server, outside the web root, with strict file permissions.

Safety rules

  1. Never commit secrets. If one was committed once, rotate it.
  2. Never print the environment (phpinfo(), print_r($_ENV)).
  3. Never send server secrets to the browser.
  4. Give each environment its own keys.
  5. Use the least privilege key each service allows.
dangerous
Prefix your own names
Use clear names (MYAPP_DB_HOST) when sharing a server with other applications. And remember that on some systems every process of the same user can read the environment of others, so do not run mixed-trust sites under one account.