Issue
I needed to add checking for placing a captcha on a site. The site was using the Laravel framework, and it needed to show a captcha in production only, and avoid showing a captcha for local or staging environments.
It was a very simple case, just needed to add checking for the environment variable “APP_ENV”, where the code for the captcha is placed. So added the checking.
On the local server, it was tested for different cases and it worked fine. On staging also worked fine.
Then on the production server, it worked fine for initial testing.
Great, so it means we are good to go on the production server. So I ran the following command to cache the environment variables:
php artisan config:cache
Time to relax, right?
NO. Captcha was not showing on the page.
Let’s start debugging…..
Debugging
After considering all other options for this issue, and failing to determine the reason, I decided to debug the condition where it was checking env(“APP_ENV”). And guess what, the problem was in that checking.
Without configuration caching env(“APP_ENV”) was returning “production”, and with configuration caching env(“APP_ENV”). was returning “null“.
Strange!!!
After searching for a few minutes and going through Laravel documentation, I figured out how to solve it.
Let’s dive into the reason for this issue and how to solve it.
Reason
Let’s take a look at Laravel documentation carefully. Especially at https://laravel.com/docs/9.x/helpers#method-env.
Here it clearly says:
If you execute the config:cache command during your deployment process, you should be sure that you are only calling the env function from within your configuration files. Once the configuration has been cached, the .env file will not be loaded and all calls to the env function will return null.
So the reason is clearly mentioned here:
Reason: When Laravel configuration is cached, the .env file is not loaded, and as the .env file is not loaded, so the env function will not work.
Solution: Get any environment variable value through the config file (as the environment variable value will be loaded from .env while generating the cache).
Let’s see how to fix this.
Solution
To avoid this situation, never use env(“ANY_VAR”) directly in your code. Instead, use it like config(“config_file_name.var_name”).
So in my case, I already had the following line in config/app.php file.
'name' => env("APP_ENV", "some_default_env_name"),
I used config(“app.name”) for checking the value in my code and the problem was solved.
// Do not use env("app.name")
// Use the following line of code
config("app.name");
Now, what if you are introducing one or more new variables in the .env file, and want to use the value in your code.
In that case, create a new file in the config directory. Say, you have new environment variables for adding a new service to your application, and you want to add XYZ_SERVICE_ID and XYZ_SERVICE_SECRET. Then add a new file named “xyz.php” in the config directory.
Then add the following lines in config/xyz.php file.
return [
'service_id' => env('XYZ_SERVICE_ID'),
'service_secret' => env('XYZ_SERVICE_SECRET'),
];
After that, you can use the values bellow:
$serviceId = config("xyz.service_id");
$serviceSecret = config("xyz.service_secret");
Just remember this, and never use “env()” directly in your code. That’s all.
# to resolve the bug ‘not save and not read from .env file’
1- delete vendor from local
2- run ‘composer install’ in the local
3- upload composer.lock from local to live server
4- upload vendor from local to live server
5- upload storage from local to live server
6- run ‘composer dump-autoload’ in the server
That’s all.