Skip to content

Instantly share code, notes, and snippets.

@eric1234
Last active March 26, 2024 06:17
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save eric1234/5628416 to your computer and use it in GitHub Desktop.
Save eric1234/5628416 to your computer and use it in GitHub Desktop.
Environment-based configuration for PHP

Purpose

Somewhat like dotenv but for PHP.

The goals is to remove all config scattered about in files and have one authoritative source for that config info.

Usage

Create a file called production.env in the root of your website. In that file put all configuration. Example:

DB_DSN=mysql:dbname=mydb;host=myhost
DB_USERNAME=myuser
DB_PASSWORD=mypass

Then in your code you can simply access these values via the $_ENV global.

You can also create a "development.env" file if your development config is different (or staging or whatever environments you want to support). Simply make the web-server set the APP_ENV environment variable so it knows which file to load. Example:

APP_ENV=development php -S localhost:5000

Now the PHP scripts will get their config from development.env.

If you don't want to clutter up your web root with a bunch of .env files simply create a "environments" subdirectory and put the files in that directory.

<?php
# https://gist.github.com/eric1234/5628416
# Avoid variables polluting namespace
namespace Env;
$_ENV['APP_ENV'] = getenv('APP_ENV');
if( !$_ENV['APP_ENV'] ) $_ENV['APP_ENV'] = 'production';
# If running under CGI the document root is often not set. Calculate
# it based on CGI variables that should be set.
if( !isset($_SERVER['DOCUMENT_ROOT']) )
$_SERVER['DOCUMENT_ROOT'] =
str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['SCRIPT_FILENAME']);
$env = "$_ENV[APP_ENV].env";
$cur = __DIR__;
$root = realpath($_SERVER['DOCUMENT_ROOT']);
$found = false;
while( !$found && strpos(realpath("$cur/$env"), $root) == 0 ) {
$file = null;
if( file_exists("$cur/.env") ) $file = "$cur/.env";
if( file_exists("$cur/$env") ) $file = "$cur/$env";
if( file_exists("$cur/environments/$env") ) $file = "$cur/environments/$env";
if( $file ) {
foreach(explode(PHP_EOL, file_get_contents($file)) as $line) {
if( empty($line) ) continue;
list($var, $val) = explode("=", $line, 2);
$_ENV[$var] = $val;
}
$found = true;
}
$cur = dirname($cur);
}
@philipborbon
Copy link

I think you should use "PHP_EOL" instead of "\n".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment