Allow to override .env files per env

This commit is contained in:
Nicolas Grekas
2018-11-09 14:22:38 +01:00
parent 5b3ce90950
commit 95bb54353e
22 changed files with 157 additions and 90 deletions
+4 -14
View File
@@ -2,23 +2,13 @@
use App\Kernel;
use Symfony\Component\Debug\Debug;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\HttpFoundation\Request;
require __DIR__.'/../vendor/autoload.php';
require dirname(__DIR__).'/vendor/autoload.php';
// The check is to ensure we don't use .env in production
if (!isset($_SERVER['APP_ENV']) && !isset($_ENV['APP_ENV'])) {
if (!class_exists(Dotenv::class)) {
throw new \RuntimeException('APP_ENV environment variable is not defined. You need to define environment variables for configuration or add "symfony/dotenv" as a Composer dependency to load variables from a .env file.');
}
(new Dotenv())->load(__DIR__.'/../.env');
}
Kernel::bootstrapEnv();
$env = $_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? 'dev';
$debug = (bool) ($_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? ('prod' !== $env));
if ($debug) {
if ($_SERVER['APP_DEBUG']) {
umask(0000);
Debug::enable();
@@ -32,7 +22,7 @@ if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? $_ENV['TRUSTED_HOSTS'] ?? false
Request::setTrustedHosts(explode(',', $trustedHosts));
}
$kernel = new Kernel($env, $debug);
$kernel = new Kernel($_SERVER['APP_ENV'], $_SERVER['APP_DEBUG']);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
@@ -6,6 +6,7 @@ use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use Symfony\Component\Routing\RouteCollectionBuilder;
@@ -58,4 +59,78 @@ class Kernel extends BaseKernel
$routes->import($confDir.'/{routes}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, '/', 'glob');
$routes->import($confDir.'/{routes}'.self::CONFIG_EXTS, '/', 'glob');
}
public static function bootstrapCli(array &$argv)
{
// consume --env and --no-debug from the command line
// when using symfony/console v4.2 or higher, this should
// be replaced by a call to Application::bootstrapEnv()
for ($i = 0; $i < \count($argv) && '--' !== $v = $argv[$i]; ++$i) {
if ('--no-debug' === $v) {
putenv('APP_DEBUG='.$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0');
$argvUnset[$i] = true;
break;
}
}
for ($i = 0; $i < \count($argv) && '--' !== $v = $argv[$i]; ++$i) {
if (!$v || '-' !== $v[0] || !preg_match('/^-(?:-env(?:=|$)|e=?)(.*)$/D', $v, $v)) {
continue;
}
if (!empty($v[1]) || !empty($argv[1 + $i])) {
putenv('APP_ENV='.$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = empty($v[1]) ? $argv[1 + $i] : $v[1]);
$argvUnset[$i] = $argvUnset[$i + empty($v[1])] = true;
}
break;
}
if (!empty($argvUnset)) {
$argv = array_values(array_diff_key($argv, $argvUnset));
}
}
public static function bootstrapEnv($env = null)
{
if (null !== $env) {
putenv('APP_ENV='.$_SERVER['APP_ENV'] = $env);
}
if ('prod' !== $_SERVER['APP_ENV'] = isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : (isset($_ENV['APP_ENV']) ? $_ENV['APP_ENV'] : null)) {
if (!class_exists(Dotenv::class)) {
throw new \RuntimeException('The "APP_ENV" environment variable is not defined. You need to set it or run "composer require symfony/dotenv" to load it from a ".env" file.');
}
// when using symfony/dotenv v4.2 or higher, this call and the related methods
// below should be replaced by a call to the new Dotenv::loadEnv() method
self::loadEnv(new Dotenv(), \dirname(__DIR__).'/.env');
}
$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : 'dev';
$_SERVER['APP_DEBUG'] = isset($_SERVER['APP_DEBUG']) ? $_SERVER['APP_DEBUG'] : (isset($_ENV['APP_DEBUG']) ? $_ENV['APP_DEBUG'] : 'prod' !== $_SERVER['APP_ENV']);
$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0';
}
private static function loadEnv(Dotenv $dotenv, $path)
{
$dotenv->load($path);
if (null === $env = isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : (isset($_ENV['APP_ENV']) ? $_ENV['APP_ENV'] : null)) {
$dotenv->populate(array('APP_ENV' => $env = 'dev'));
}
if ('test' !== $env && file_exists($p = "$path.local")) {
$dotenv->load($p);
$env = isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : (isset($_ENV['APP_ENV']) ? $_ENV['APP_ENV'] : $env);
}
if (file_exists($p = "$path.$env")) {
$dotenv->load($p);
}
if (file_exists($p = "$path.$env.local")) {
$dotenv->load($p);
}
}
}
+2 -1
View File
@@ -18,7 +18,8 @@
"#TRUSTED_HOSTS": "localhost,example.com"
},
"gitignore": [
"/.env",
"/.env.local",
"/.env.*.local",
"/%PUBLIC_DIR%/bundles/",
"/%VAR_DIR%/",
"/vendor/"
+4 -14
View File
@@ -2,23 +2,13 @@
use App\Kernel;
use Symfony\Component\Debug\Debug;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\HttpFoundation\Request;
require __DIR__.'/../vendor/autoload.php';
require dirname(__DIR__).'/vendor/autoload.php';
// The check is to ensure we don't use .env if APP_ENV is defined
if (!isset($_SERVER['APP_ENV']) && !isset($_ENV['APP_ENV'])) {
if (!class_exists(Dotenv::class)) {
throw new \RuntimeException('APP_ENV environment variable is not defined. You need to define environment variables for configuration or add "symfony/dotenv" as a Composer dependency to load variables from a .env file.');
}
(new Dotenv())->load(__DIR__.'/../.env');
}
Kernel::bootstrapEnv();
$env = $_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? 'dev';
$debug = (bool) ($_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? ('prod' !== $env));
if ($debug) {
if ($_SERVER['APP_DEBUG']) {
umask(0000);
Debug::enable();
@@ -32,7 +22,7 @@ if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? $_ENV['TRUSTED_HOSTS'] ?? false
Request::setTrustedHosts(explode(',', $trustedHosts));
}
$kernel = new Kernel($env, $debug);
$kernel = new Kernel($_SERVER['APP_ENV'], $_SERVER['APP_DEBUG']);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
@@ -5,7 +5,9 @@ namespace App;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Console\Application;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use Symfony\Component\Routing\RouteCollectionBuilder;
@@ -58,4 +60,29 @@ class Kernel extends BaseKernel
$routes->import($confDir.'/{routes}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, '/', 'glob');
$routes->import($confDir.'/{routes}'.self::CONFIG_EXTS, '/', 'glob');
}
public static function bootstrapCli(array &$argv)
{
// consume --env and --no-debug from the command line
Application::bootstrapEnv($argv);
}
public static function bootstrapEnv(string $env = null)
{
if (null !== $env) {
putenv('APP_ENV='.$_SERVER['APP_ENV'] = $env);
}
if ('prod' !== $_SERVER['APP_ENV'] = $_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) {
if (!class_exists(Dotenv::class)) {
throw new \RuntimeException('The "APP_ENV" environment variable is not defined. You need to set it or run "composer require symfony/dotenv" to load it from a ".env" file.');
}
(new Dotenv())->loadEnv(\dirname(__DIR__).'/.env');
}
$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $_SERVER['APP_ENV'] ?? $_SERVER['APP_ENV'] ?? 'dev';
$_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV'];
$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0';
}
}