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 theenv
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
Try/Catch Block in PHP Not Catching Exception
How to Block Uploads of Nude Images
Check If a String Contain Multiple Specific Words
What Are the Benefits of Oo Programming? Will It Help Me Write Better Code
Best Way to Do a Weighted Search Over Multiple Fields in MySQL
Upload Multiple Images with Jquery Ajax and Process Them with PHP
How to Convert Between 12 Hour Time and 24 Hour Time in PHP
How to Pass Param from Controller to Layout in Yii2
A Restful Persistence Solution Usable with Backbone.Js... in PHP