Codeskill

Learn to code, step by step

Config, environments, and secrets

Config, environments, and secrets. Hard-coding database passwords in source files works until you push to GitHub and regret it.

Config as a returned array

<?php
// config/app.php
declare(strict_types=1);

return [
    'debug' => false,
    'name'  => 'My App',
    'url'   => 'https://example.com',
];
$config = require dirname(__DIR__) . '/config/app.php';
$dbConfig = require dirname(__DIR__) . '/config/database.php';

.env for secrets (local)

Use a .env file for machine-specific values. Never commit it. Add .env to .gitignore. Commit .env.example with empty placeholders instead.

# .env.example
APP_DEBUG=true
APP_URL=http://localhost:8080

DB_HOST=127.0.0.1
DB_NAME=myapp
DB_USER=
DB_PASS=

Load .env with vlucas/phpdotenv (composer require vlucas/phpdotenv) or a tiny parser you write yourself.

$dotenv = DotenvDotenv::createImmutable(dirname(__DIR__));
$dotenv->safeLoad();

$host = $_ENV['DB_HOST'] ?? '127.0.0.1';

Environment-specific config

$env = $_ENV['APP_ENV'] ?? 'production';

$config = require __DIR__ . '/app.php';
$local = __DIR__ . "/app.$env.php";

if (file_exists($local)) {
    $config = array_merge($config, require $local);
}

Secrets on production

  • Set env vars in the hosting panel or server config – not in git
  • Rotate keys if they leak
  • Different DB credentials per environment
  • Turn off debug in production (APP_DEBUG=false)

What belongs in config

  • Database DSN parts, mail SMTP host, API base URLs
  • Feature flags (maintenance mode, registration open)
  • Not business rules that change often – those live in code or the database

Treat secrets like house keys. Config files describe the app; .env holds the keys. Keep them out of version control.

PreviousTwig or plain PHP templates – keeping HTML out of logic