Laravel 5 load env file based on .env.master?

Definitely, me myself I tend to "bend" a framework little bit everytime and there's always a way, not always the best solution though. I'm not giving a whole implementation here, just pointing you in some direction, that might work for you.

You can extend Laravel's base application class Illuminate\Foundation\Application, which contains $environmentFile variable storing environment file loaded during appplication bootstrap or possibly override function loadEnvironmentFrom($file) or environmentFile(). The whole logic is up to you.

So basically all you need to do in order to be able to "play" with .env loading is...

Create a new application class extending Laravel's one:

namespace MyNamespace;
...

use Illuminate\Foundation\Application as App;

/**
 * I'm doing alots of magic with .env in this class
 */
class Application extends App
{
    ... 

    /**
     * The environment file to load during bootstrapping.
     *
     * @var string
     */
    protected $environmentFile = '.env.main';

    ...
}

And now, because we have a new bootstraping class, we have to tell Laravel we want to use it. So you'll have to modify bootstrap/app.php file in point where a new instance is being created:

...
$app = new MyNamespace\Application(
    realpath(__DIR__.'/../')
);
...

Note: For inspiration I recommend you to really look at Illuminate\Foundation\Application class.


In laravel 5.5+ you can, maybe earlier, you can set your server have a APP_ENV environment or server variable that the process can see (apache, command line...)

this will allow you to use a suffix or file extension on your .env files for auto loading those files...

  • APP_ENV=dev :: .env.dev
  • APP_ENV=production :: .env.production

much easier than other solutions.

If you want to look into how this is done, it starts with

1. application bootstrappers

protected $bootstrappers = [
    \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
    \Illuminate\Foundation\Bootstrap\LoadConfiguration::class,
    \Illuminate\Foundation\Bootstrap\HandleExceptions::class,
    \Illuminate\Foundation\Bootstrap\RegisterFacades::class,
    \Illuminate\Foundation\Bootstrap\SetRequestForConsole::class,
    \Illuminate\Foundation\Bootstrap\RegisterProviders::class,
    \Illuminate\Foundation\Bootstrap\BootProviders::class,
];

2. LoadEnvironmentVariables

first the environment is determined…

\Illuminate\Foundation\Bootstrap\LoadConfiguration::bootstrap calls \Illuminate\Foundation\Application::detectEnvironment

If

--env={env} for CLI then it will use that for APP_ENV.

Else

\Illuminate\Foundation\EnvironmentDetector::detectWebEnvironment is called which uses a callback…

function () use ($config) {
            return $config->get('app.env', 'production');
        }

where app.env defaults to env('APP_ENV', 'production')

3 LoadConfiguration

\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::bootstrap calls... \Illuminate\Foundation\Application::afterLoadingEnvironment which eventually gets to

\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::checkForSpecificEnvironmentFile

which sets the environment file based on app env IF the file exists.

        $this->setEnvironmentFilePath(
            $app, $app->environmentFile().'.'.env('APP_ENV')
        );

allowing it to load the .env.{APP_ENV} instead of .env

NOTE: Testing.

when running php unit tests. the Illuminate/Foundation will try to load the .env.testing file for configurations!

Tags:

Php

Laravel