29

In laravel 4 we had:

$env = $app->detectEnvironment(array(
    'local' => array('homestead')
));

by default.

But in laravel 5 it's changed to:

$env = $app->detectEnvironment(function()
{
    return getenv('APP_ENV') ?: 'production';
});

Also, they have excluded .env.* line in .gitignore, now it has:

.env

And added file .env.example:

APP_ENV=local
APP_KEY=SomeRandomString
DB_USERNAME=homestead
DB_PASSWORD=homestead

So, if i have more than 2 environments, do i have to set all of them in a single .env file now? E.g.:

APP_ENV=local
DB_PASSWORD=123

APP_ENV=alpha
DB_PASSWORD=456

If i would have no .env file, how laravel will know what environment i am using?

Jeff Puckett
  • 37,464
  • 17
  • 118
  • 167
Alexander Kim
  • 17,304
  • 23
  • 100
  • 157
  • Hi Heihachi, in laravel-5, In which folder .ENV file is situated. I'm not able to find that file. Can you please help me. – Nana Partykar Sep 04 '15 at 11:48

5 Answers5

30

You can do it exactly the same as in Laravel 4:

$env = $app->detectEnvironment(array(
    'local' => array('homestead')
));

*.env file are just used to put sensitive data that shouldn't be put into VCS. The same is in Laravel 4

but is seems that in last days default detectEnvironment was changed to:

$env = $app->detectEnvironment(function()
{
    return getenv('APP_ENV') ?: 'production';
});

so you can use either setting variable from PC name or from ENV file.

If you use ENV based environment detection in main env file (by default .env file you need to add:

APP_ENV=local

Of course local here is local environment, you can change it into production or dev

At the moment the most important issue I see is that you need to remember when going on production to change this .env file content from APP_ENV=local to APP_ENV=production so in my opinion much better method is the old default method based on PC names.

Now ENV files. If you use ENV based environment detection, you should put into your ENV file only:

APP_ENV=local

Now you can create separate ENV files for your different environments for example:

.local.env :

 MY_DB=testdb

.production.env :

MY_DB=productiondb

and now in bootstrap.environment.php file you can modfiy:

if (file_exists(__DIR__.'/../.env'))
{
    Dotenv::load(__DIR__.'/../');
}

into:

if (file_exists(__DIR__.'/../.env'))
{
    Dotenv::load(__DIR__.'/../');

    if (getenv('APP_ENV') && file_exists(__DIR__.'/../.' .getenv('APP_ENV') .'.env')) {
        Dotenv::load(__DIR__ . '/../', '.' . getenv('APP_ENV') . '.env');
    }   
}

to load extra env file based on APP_ENV from main env file.

Now you will be able to use it in your other configuration file as always: $_ENV['MY_DB']

clone45
  • 8,952
  • 6
  • 35
  • 43
Marcin Nabiałek
  • 109,655
  • 42
  • 258
  • 291
  • Thanks, without modifying environment.php i can use only one .env file, right? also i can set APP_ENV just once? – Alexander Kim Oct 14 '14 at 05:48
  • And i think this new "way" is more convenient than an old one. Because everytime you deploy from github/bitbucket you will have to create .env file with required environment and variables. – Alexander Kim Oct 14 '14 at 06:09
  • @Heihachi Yes, it will only load `.env` file by default so you couldn't have 2 ENV with settings for different environments. Of course if you can, one file is enough if you will use in your config files different env variables names for different environments. – Marcin Nabiałek Oct 14 '14 at 06:55
  • But what if we have no .env file at all? How laravel will know what environment we are using? I am working on local VM and printing App::environment(); and it shows local. How does it know that i'm on local environment, not production? – Alexander Kim Oct 14 '14 at 08:05
  • @MarcinNabiałek - you should update your answer - as I think only ENV remains in the latest L5? – Laurence Nov 05 '14 at 12:09
  • @TheShiftExchange I haven't looked at L5 very close because it's still changing but you are right - something could changed but it was working at the moment of answering – Marcin Nabiałek Nov 05 '14 at 12:16
  • i found this same solution with some browsing. well, put, and this is what i believe should be followed through development phase. i don't know why the support was suppressed. – rolfk Apr 23 '15 at 07:13
  • @MarcinNabiałek Sorry i am not so familiar with the new framework structure. Would like to ask so if i have multiple environments how/where should I configure it and asks the system to determine which environment am I in? Previously when i was in L4.2 I did it in such a way `$env = $app->detectEnvironment(array( 'local' => array('homestead'), 'development' => array('develop.example.com'), 'production' => array('example.com'), ));` – Kenny Yap May 21 '15 at 08:03
  • 1
    In the latest L5 (5.1) release there is no `bootstrap.environment.php` file anymore. See Anthony Pillos answer at http://stackoverflow.com/a/29424899/413531 on how to get it to work in L5. – Hirnhamster Oct 21 '15 at 21:51
12

For those who just upgraded to 5.2:

You cannot longer use the static Dotenv::load() method. Use the following instead:

$dotenv = new Dotenv\Dotenv(__DIR__ . '/../', '.' . getenv('APP_ENV') . '.env'); // Laravel 5.2
$dotenv->load();

in bootstrap/app.php.

//edit Soo.. after digging into this for the past hour I might as well add some additional info here:

  • Laravel uses .env files for configuration
  • By default, the file ".env" in the root directory of the application is loaded
  • You can access the values within those .env files via the env() helper function or directly via PHP's native getenv() function. Although you should only do so to fill your config files (see /config/*.php), because those can be cached.
  • the .env files are loaded in the DetectEnvironment class. I found this helpful while debugging to set breakpoints. Please take note of the line (new Dotenv($app->environmentPath(), $app->environmentFile()))->load();: Since it uses load() any environment value that has already been set will not be overwritten! (You would have to use overload() to do so - this drove me nuts because homestead sets the APP_ENV variable to local in the php-fpm config /etc/php/7.0/fpm/php-fpm.conf and you cannot change it via .env file)
  • when writing unit tests, you usually inherit from TestCase, which sets the APP_ENV variable to testing (via refreshApplication() -- using putenv() to override the default local value)
Hirnhamster
  • 7,101
  • 8
  • 43
  • 73
  • You saved my day. My .env suddenly didn't load. I had to change your code to get it to work for me: `$dotenv = new Dotenv\Dotenv(__DIR__.'/../');` Could this be a problem in the future? – Carsten Feb 01 '16 at 14:44
1

I just wanted to contribute my solution for Laravel 5.1, which is slightly simpler IMHO. In bootstrap/app.php, I have (just after where the Application is instantiated):

$app->beforeBootstrapping(\Illuminate\Foundation\Bootstrap\DetectEnvironment::class, function() use ($app) {
    $suffix = (env('APP_ENV')) 
        ? '.'.env('APP_ENV') 
        : '';
    $app->loadEnvironmentFrom('.env'.$suffix);
});

There's no need for any checking or error handling. Laravel will default to "production" if the file is not found.

That is all.

thefuzzy0ne
  • 479
  • 3
  • 10
0

The fact that you can't have more than one .env file by default and that it's excluded in .gitignore is intentional and is the intended way to manage environments. The .env file should not be in version control and should be configured per environment. .env sets your environment and all environment variables.

So, if i have more than 2 environments, do i have to set all of them in a single .env file now?

No. You would have a .env file in each place that you have your application installed. The difference is in what is inside that file.

Additionally, because the .env file is simply a key-value store, any subsequent declarations would overwrite previous ones. In your example, Laravel would never see your "local" settings.

It seems odd at first, but this new default system is actually generally easier and less prone to the issues the "4.2 way" had/has, as there's no place for logic errors.

If i would have no .env file, how laravel will know what environment i am using?

It wouldn't run at all. In the .env file is also an APP_KEY declaration, which Laravel will not run without. Without a .env file, you would get a 500 server error.

Shauna
  • 9,495
  • 2
  • 37
  • 54
  • I understand the logic behind one `.env` file, but it all falls apart in the case of an automated CI system. We use TravisCI in GitHub which sets itself up and tears itself down on the fly. Without committing `.env` file to GitHub, how can I set up my Travis environment to look at the correct database etc...? – Brandon May 17 '17 at 19:58
  • 1
    @Brandon -- if you've set up your config.php files correctly, then you can set up the server environment, itself, if you so choose, so you'd add it into the configuration for the CI system, itself. You'll probably find [this discussion](https://laracasts.com/discuss/channels/general-discussion/using-several-env-files-within-my-app-general-and-testing?page=2) useful. There's [this technique](https://alfrednutile.info/posts/148), as well. – Shauna May 18 '17 at 22:04
0

For Laravel version 10 and above:

You can actually use this package syamsoul/laravel-set-env

  1. Just install via composer
composer require syamsoul/laravel-set-env
  1. Run this command:
php artisan souldoit:set-env
  • And you will be prompted to insert the variable name and the value.
  • Or can straightaway insert the variable name and the value into the argument, for example:
php artisan souldoit:set-env "MY_APP_NAME=My Application"
Syamsoul Azrien
  • 2,534
  • 4
  • 32
  • 55