A environment variable is a variable whoes value is set before the program runs. When program compiles environment variable can be used in the program.
Let say that you are working on a big website project. Developers are working on their local machine we call it local environment.
When website is deployed to remote server for live traffic that environment we call it production environment. When you are working locally you might not want to send emails to real users.
Therefore you need to define a boolean variable i,e, SEND_EMAIL which is false in development or local environment however it is true in production environment,
Let's look at following diagram:
Now, you have three different environment here:
- local or development
- staging i.e. exact like production environment where we test changes before we go live
- production
As your project grows you need more variables based on different environment. Laravel helps you manage these environment in nicer way.
When you first download your laravel project you will see that in the root directory of your project there should be a file called: .env.example
This .env.example is copied to .env file when your composer install command runs. Now, this ,env file is added to your .gitignore file and should never be committed to your repository.
Purpose of this .env file is that it can be different based on different working environment.
When you deploy your project to either staging or production server you have to manually create a new .env file for each environment so that it can hold same variable with different values in each environment.
Most important point here is that you never add your production credentials in .env file and commit to your repository. You would have to create this file manually on prod environment.
Anytime you add or remove environment variable from this file you would have to manually update this variable on each environment.
Let's not go more in depth at this moment and understand how we can define and use this variable in laravel framework.
What is the purpose of env variables in Laravel?
As we know that depending on environment we work on we might have different variable value. In laravel framework .env file contains set of key/value pair variables.
These variables have different values depending on environment they are used in. Once environment values are defined in .env file it can be used by config files defined in config/ folder or can directly be used in laravel.
Let's look at some sample env variables defined in .env file:
APP_NAME=Laravel APP_ENV=local APP_KEY= APP_DEBUG=true APP_URL=http://localhost LOG_CHANNEL=stack LOG_DEPRECATIONS_CHANNEL=null LOG_LEVEL=debug DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel_9 DB_USERNAME=root DB_PASSWORD= BROADCAST_DRIVER=log CACHE_DRIVER=file FILESYSTEM_DISK=local QUEUE_CONNECTION=sync SESSION_DRIVER=file SESSION_LIFETIME=120 MEMCACHED_HOST=127.0.0.1 REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379 MAIL_MAILER=smtp MAIL_HOST=mailhog MAIL_PORT=1025 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS="hello@example.com" MAIL_FROM_NAME="${APP_NAME}" AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_DEFAULT_REGION=us-east-1 AWS_BUCKET= AWS_USE_PATH_STYLE_ENDPOINT=false PUSHER_APP_ID= PUSHER_APP_KEY= PUSHER_APP_SECRET= PUSHER_APP_CLUSTER=mt1 MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
All of the variables listed in this file will be loaded into the $_ENV
PHP super-global when your application receives a request.
Laravel gives you helper function to retrive this variable. Let's look at how we can use this defined variables:
How to retrieve env variable from .env file in laravel?
You can use laravel env helper function to retrieve the value of env variable defined in .env file. Let's look at the example below:
# let's fetch APP_ENV variable from .env file $environment = env('APP_ENV')
You will find lot of examples of this function in config directory where laravel stores configuration files. If you want to learn what are configuration file please read below article:
Let's open sample config file located at config/app.php to see some example usage of this function:
<?php use Illuminate\Support\Facades\Facade; return [ /* |-------------------------------------------------------------------------- | Application Name |-------------------------------------------------------------------------- | | This value is the name of your application. This value is used when the | framework needs to place the application's name in a notification or | any other location as required by the application or its packages. | */ 'name' => env('APP_NAME', 'Laravel'), /* |-------------------------------------------------------------------------- | Application Environment |-------------------------------------------------------------------------- | | This value determines the "environment" your application is currently | running in. This may determine how you prefer to configure various | services the application utilizes. Set this in your ".env" file. | */ 'env' => env('APP_ENV', 'production'), // some other variables goes here ];
env helper function takes two argument first key defined in ,env file and second argument is default value. Let say that if you have not defined variable in .env file you can use default value.
env function will not throw any error if variable is not defined.
Determining The Current Environment
Apart from env helper function laravel also give you some other helper function that you can use in your controller or anywhere in laravel application.
Let say that you want to determine current environment in your code somewhere you can make use of following helper function to determine what is the current environment.
Let's look at how we can find current working environment in laravel using facade:
use Illuminate\Support\Facades\App; # fetch current env from the .env file i.e. APP_ENV variable $environment = App::environment(); // check if current environment is local if (App::environment('local')) { // run your code specific to this environment } // check if current environment is local or staging if (App::environment(['local', 'staging'])) { // run your code specific to this environment }
You can also use similar logic without using facade let's see how we can do that:
if (app()->environment('local')) { // run your code specific to this environment } if (app()->environment(['local', 'staging'])) { // run your code specific to this environment. }
How does laravel load .env file? Can we use multiple .env files?
Let say that you are setting APP_ENV variable outside of .env file somewhere and when laravel application boots it first try to find following env file in order:
- .env.[APP_ENV] if this file is not found it will try to find .env file
For unit testing if you are using phpunit.xml file where you set APP_ENV=testing and you can create a new file called .env.testing along with .env file without affecting .env variables.
This is useful when you are testing unit test and writing code at the same time you can have:
- .env
- .env.testing
file when you run unit test laravel will load .env.testing file while normally web server will load ,env file. You can use different database variable for both environement without affecting each environment.
Security risk for .env file
You should never ever commit .env file to external source control. Each developer might have different .env depending on their use. You should also never put any real credentials in .env.example file.
If hacker gain access to your source control .env.example file your production can be compromised.