Skip to content

Instantly share code, notes, and snippets.

@msankhala
Last active February 29, 2024 04:53
Show Gist options
  • Star 38 You must be signed in to star a gist
  • Fork 15 You must be signed in to fork a gist
  • Save msankhala/3c282abf546318a2662e to your computer and use it in GitHub Desktop.
Save msankhala/3c282abf546318a2662e to your computer and use it in GitHub Desktop.
Setup Multiple Environment for Laravel 5 Developers Way
<?php
/*
|--------------------------------------------------------------------------
| Follow this instructions:
|--------------------------------------------------------------------------
|
| Laravel takes a dead simple approach to your application environments
| so you can just specify a machine name for the host that matches a
| given environment, then we will automatically detect it for you.
|
| 1. Check if you have .env file (it should be automatically created by laravel)
|
| REMOVE all the contents from here, and just put: local or production
| (whatever environment you want). This will be the one that will be
| changed when you want to switch to another environment. :D
|
| 2. Create new Environment file let say you have your local and production enviroment.
|
| Create a file with the name of: .local.env
| Create a file with the name of: .production.env
|
| 3. Add default environment value.
|
| For Local Environment (.local.env file)
| APP_ENV=local
|
| For Production Environment (.production.env file)
| APP_ENV=production
|
| 4. Create new php file and named it, environment.php, save it into this folder: app/bootstrap/environment.php
| – Inside of this file we will do the magic. Insert this snippet code.
*/
/*
|--------------------------------------------------------------------------
| Detect The Application Environment
|--------------------------------------------------------------------------
|
| Laravel takes a dead simple approach to your application environments
| so you can just specify a machine name for the host that matches a
| given environment, then we will automatically detect it for you.
|
*/
$env = $app->detectEnvironment(function(){
$environmentPath = __DIR__.'/../.env';
$setEnv = trim(file_get_contents($environmentPath));
if (file_exists($environmentPath))
{
putenv("APP_ENV=$setEnv");
if (getenv('APP_ENV') && file_exists(__DIR__.'/../.' .getenv('APP_ENV') .'.env')) {
Dotenv::load(__DIR__ . '/../', '.' . getenv('APP_ENV') . '.env');
}
}
});
/*
|
| 5. This snippet code, use, putenv php function to set APP_ENV and then using
| the Dotenv package by vlucas. I’m loading the file that we created and
| base on the .env file we can determine which environment should we use.
|
| 6. Include your environment.php file in bootstrap file. Paste it inside your
| bootstrap/app.php file.
|
*/
/*
|--------------------------------------------------------------------------
| Load Environment File on Startup
|--------------------------------------------------------------------------
|
| This will determine, which environment will be loaded for our application.
|
*/
require __DIR__.'/environment.php';
// 6. After that you can check which environment is being loaded using:
App::environment()
// 7. I output the current environment in my Laravel 5 Welcome Page, You can see my screenshots below:
Copy link

ghost commented Feb 6, 2018

For anyone looking at this gist, here is the improved version, tested on laravel 5.4

Make an .env file with following contents
APP_ENV=local
or
APP_ENV=production

Create a new file in bootstrap directory.

/*
|--------------------------------------------------------------------------
| Code in bootstrap/environment.php
|--------------------------------------------------------------------------
| Detect The Application Environment
|--------------------------------------------------------------------------
|
| Dotenv package is not accessible in the file so we will use the other way around.
| Create an instance of Dotenv class which takes two parameters:
| $dotenv = new Dotenv\Dotenv(path_to_env_file, name_of_file);
|
*/
$env = $app->detectEnvironment(function(){
    $environmentPath = __DIR__.'/../.env';
    $setEnv = trim(file_get_contents($environmentPath));
    if (file_exists($environmentPath))
    {
        putenv("$setEnv");
        if (getenv('APP_ENV') && file_exists(__DIR__.'/../.' .getenv('APP_ENV') .'.env')) {
        	$dotenv = new Dotenv\Dotenv(__DIR__.'/../', '.'.getenv('APP_ENV').'.env');
        	$dotenv->load();
        } 
    }
});

Include the environment.php in bootstrap/app.php

/*
|--------------------------------------------------------------------------
| Load Environment File on Startup
|--------------------------------------------------------------------------
|
| This will determine, which environment will be loaded for our application.
|
*/
require __DIR__.'/environment.php';

@ahsankhatri
Copy link

Or if you want to override few variables on some conditional then use this in environment.php (enhanced version of @tahir-se's solution)

$app->afterLoadingEnvironment(function() use($app) {
    if (getenv('APP_ENV') && file_exists(__DIR__.'/../.' .getenv('APP_ENV') .'.env')) {
        $dotenv = new Dotenv\Dotenv(__DIR__.'/../', '.'.getenv('APP_ENV').'.env');
        $dotenv->overload();
    }
});

@amun1303
Copy link

@tahir-se Thanks so much!

@teddykishi
Copy link

A little update

$env = $app->detectEnvironment(function(){
    $environmentPath = __DIR__.'/../.env';
    $setEnv = trim(file_get_contents($environmentPath));
    if (file_exists($environmentPath))
    {
    	putenv("$setEnv");
        if (getenv('APP_ENV') && file_exists(__DIR__.'/../.' .getenv('APP_ENV') .'.env')) {
        	$dotenv = Dotenv\Dotenv::create(__DIR__.'/../', '.'.getenv('APP_ENV').'.env');
			$dotenv->overload();
        }
    }
});

@infureal
Copy link

infureal commented Oct 10, 2019

This is my implementation for using local and production env:

use Dotenv\Dotenv;

$env = $app->detectEnvironment(function () {

    $whitelist = [
        "127.0.0.1",
        "::1"
    ];

    $envPath = realpath(dirname(__DIR__));

    // Production ENV
    $envFile = ".env";

    // If is localhost change to Local ENV
    if (in_array($_SERVER["REMOTE_ADDR"], $whitelist))
        $envFile = ".local.env";

    $env = Dotenv::create($envPath, $envFile);
    $env->overload();

});

As previous you can copy this to bootstrap/evironment.php. As well you can move $whitelist to config/app.php and call it from that file:

$whitelist = config('app.local_ip'); // or whitelist

Tested on Laravel 6.x ONLY

Copy link

ghost commented Oct 17, 2019

Notice: Undefined variable: app in C:\wamp64\www\laravel\bootstrap\environment.php on line 13
Fatal error: Uncaught Error: Call to a member function detectEnvironment() on null in C:\wamp64\www\laravel\bootstrap\environment.php on line 13
Error: Call to a member function detectEnvironment() on null in C:\wamp64\www\laravel\bootstrap\environment.php on line 13

Please help

@timbkbasic
Copy link

@r4rishabhgupta

detectEnvironment() must be called on $app. Your error suggests that $app is null, which means your $app has not been created yet. If you are including environment.php in bootstrap/app.php, as the original post suggests, then that include must come after $app is created. $app is created by these lines of code:

$app = new Illuminate\Foundation\Application(
    $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);

So, your include of environment.php must come after those lines.

@sdjhoanborges
Copy link

This is my implementation for using local and production env:

use Dotenv\Dotenv;

$env = $app->detectEnvironment(function () {

    $whitelist = [
        "127.0.0.1",
        "::1"
    ];

    $envPath = realpath(dirname(__DIR__));

    // Production ENV
    $envFile = ".env";

    // If is localhost change to Local ENV
    if (in_array($_SERVER["REMOTE_ADDR"], $whitelist))
        $envFile = ".local.env";

    $env = Dotenv::create($envPath, $envFile);
    $env->overload();

});

As previous you can copy this to bootstrap/evironment.php. As well you can move $whitelist to config/app.php and call it from that file:

$whitelist = config('app.local_ip'); // or whitelist

Tested on Laravel 6.x ONLY

working on laravel 6

@pawan-singleinterface
Copy link

Argument 1 passed to Dotenv\Dotenv::create() must implement interface Dotenv\Repository\RepositoryInterface, string given.

In Laravel 7 Dotenv create method modified. Please help

@AlbertoTorre
Copy link

For the next person wondering that, the documentation exists and you can read this: https://github.com/vlucas/phpdotenv#immutability-and-repository-customization

@femz12
Copy link

femz12 commented Dec 10, 2020

This works for me on Laravel V8

<?php
use Dotenv\Dotenv;

$env = $app->detectEnvironment(function(){
    $environmentPath = __DIR__.'/../.env';
    
    if (file_exists($environmentPath))
    {
        $setEnv = trim(file_get_contents($environmentPath));
        putenv('APP_ENV='.$setEnv);
        $dotenv = Dotenv::createImmutable(__DIR__ . '/../', '.' . getenv('APP_ENV') . '.env');
        $dotenv->load(); //this is important
    }
});

@adam1010
Copy link

In Laravel 10, at the end of bootstrap/app.php I did this to include an ADDITIONAL .env file that I wanted to use

$app->afterLoadingEnvironment(function (Illuminate\Foundation\Application $app) {
    Dotenv::create(Env::getRepository(), $app->environmentPath(), '.env-overrides')
        ->safeLoad();
});

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