What's the Correct Way to Set Env Variables in Laravel 5

What's the correct way to set ENV variables in Laravel 5?

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']

How to set .env values in laravel programmatically on the fly

Since Laravel uses config files to access and store .env data, you can set this data on the fly with config() method:

config(['database.connections.mysql.host' => '127.0.0.1']);

To get this data use config():

config('database.connections.mysql.host')

To set configuration values at runtime, pass an array to the config helper

https://laravel.com/docs/5.3/configuration#accessing-configuration-values

Accessing Laravel .env variables in blade

Five most important commands if your Laravel is not working as expected after some modifications in .env or database folder or because of any other modifications.
Here is full explanation:
https://www.youtube.com/watch?v=Q1ynDMC8UGg

php artisan config:clear
php artisan cache:clear
composer dump-autoload
php artisan view:clear
php artisan route:clear

Laravel 5 : How to set environment mode

Other answers/comments are wrong.

You only store one .env per environment. That is:

  • Your local machine will have a .env with your local config
  • The staging maching will have a .env with your staging config,
    and
  • Your production maching will have a .env with your production config

So it is always one .env file per machine. Laravel will load that config from that file.

note that .env file is in .gitignore, .env.example is not


When testing on local machine using PHPUnit you can add env variables in phpunit.xml

<php>
<env name="APP_ENV" value="testing"/>
<env name="APP_DEBUG" value="true"/>
<env name="APP_KEY" value="some crazy value"/>
<env name="DB_DRIVER" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
</php>

How to set environment variables for Laravel 5 on AWS EC2 with MySQL

You could create a new .env on your ec2 instance and add all the env vars in there. One option would be ssh-ing into the box and creating the file via vi or cat. Or you could write a script to remotely pull the .env in from an external location.

You could also ssh into the box and export APP_ENV=production all your env vars (assuming that's the right command for your OS).

Adding env vars to your environment will depend on the OS that your ec2 instance is running, so the solution will depend on that. ec2 has a concept of 'tags' which might be useful, but the docs show they limit the number of tags to 10, so you may have to do it manually and per ec2 instance :/

See here for one method that uses tags to pull in and set env vars (non-laravel specific).

I just went through this yesterday while getting Laravel running on Elastic Beanstalk, the solution was clean. You can actually set the env vars directly via the aws console (EB app/environment -> Configuration -> Software Configuration -> Environment Properties).

Update:

The key concept to understand is that Laravel just uses phpdotenv to dump vars from the .env file into php's global $_ENV, whereas any already existing env vars are automatically included in $_ENV when php starts the server (docs). So the .env file itself is unnecessary, really just a dev convenience. (unless I've just been spoiled by elastic beanstalk so far).

Laravel set environment variable

This environment you set on php artisan seve is just for that particular command, running on cli.

Note that this is not you application running, just a webserver, provided by PHP so you don't need to install a full apache or nginx to test your application.

Your web application will run under a different environment and you still need to provide a correct environment adding it to your bootstrap/start.php file:

$env = $app->detectEnvironment(array(

'local' => array('localhost', '127.0.0.1', 'example.com'),

));

Laravel Environment Variables 5.3 setup

The reasons behind this design are mainly:

  • Security concerns
  • Different environments might need different settings

Laravel makes use of the DotEnv PHP library by Vance Lucas to provide the .env functionality, so you can read more about it there as well as in the officiall Laravel docs:

Your .env file should not be committed to your application's source
control, since each developer / server using your application could
require a different environment configuration
.

If you are developing with a team, you may wish to continue including
a .env.example file with your application. By putting place-holder
values in the example configuration file, other developers on your
team can clearly see which environment variables are needed to run
your application.

And from DotEnv:

The .env file is generally kept out of version control since it can
contain sensitive API keys and passwords
. A separate .env.example file
is created with all the required environment variables defined except
for the sensitive ones, which are either user-supplied for their own
development environments or are communicated elsewhere to project
collaborators. The project collaborators then independently copy the
.env.example file to a local .env and ensure all the settings are
correct for their local environment, filling in the secret keys or
providing their own values when necessary. In this usage, the .env
file should be added to the project's .gitignore file so that it will
never be committed by collaborators. This usage ensures that no
sensitive passwords or API keys will ever be in the version control
history so there is less risk of a security breach, and production
values will never have to be shared with all project collaborators.

In summary, if you're certain that you will deploy to only one system and settings will always be the same, and there is no sensitive data inside the .env (or you're OK with everyone involved seeing it), then you could probably go ahead with your solution.

As a side node: Since you were asking for design decisions specifically, DotEnv was apparently inspired by The Twelve-Factor App, which advocates strict separation of config from code among other factors.

Laravel 5 - env() always returns null

env(...) function will not work after you cached the config. (starting from laravel 5.2 till current 5.7)

The Laravel documentation says

If you are using the config:cache command during deployment, you must make sure that you are only calling the env function from within your configuration files, and not from anywhere else in your application.

So the correct answer would be to

If you are calling env from within your application, it is strongly recommended you add proper configuration values to your configuration files and call env from that location instead, allowing you to convert your env calls to config calls.

And I quoted it from the same documentation

But for a quick fix this will do:

php artisan config:clear

And now it should be clear why, when you tried config:cache, it did not help, even though it clears the config prior to caching.

Laravel 5.2 dynamic environment variables based on user

Yes it is possible, but not in the .env file. Instead, you can move your logic to middleware:

Step 1: Add default values to the application config

Open your app/config/app.php and add your default values to the existing array.

<?php

return [
'APP_ID' => '45678',
'APP_SECRET' => 'abc456',
...
];

Step 2: Create a new Middleware

php artisan make:middleware SetAppConfigForUserMiddleware

Edit the file to look like this:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;

class SetAppConfigForUserMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$authorizedUser = Auth::user();

if (!App::runningInConsole() && !is_null($authorizedUser)) {
Config::set('app.APP_ID', 'appidOfUser' . $authorizedUser->name);
Config::set('app.APP_SECRET', 'appsecretOfUser' . $authorizedUser->email);
}
return $next($request);
}
}

Step 4: Run your middleware

If you need to set this config for the user in all the web routes you can add to the $middlewareGroups array in app/Http/kernel.php. This will apply the middleware to all the routes inside web.php.

/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
...
\App\Http\Middleware\SetAppConfigForUserMiddleware::class,
],

Step 5: Testing

For example, my Auth:user()->name is "John" and my Auth:user()->email is "john@example.com"

If you put this in your resources/views/home.blade.php

App Id Of User <code>{{config('app.APP_ID')}}</code>
App Secret Of User <code>{{config('app.APP_SECRET')}}</code>

The result will be appidOfUserJohn and appsecretOfUserjohn@example.com.



Related Topics



Leave a reply



Submit