If you make requests fast enough some or all environment variables return null.
To reproduce:
This bug occurs for me using WAMP 2.5 x64 (latest) on Windows 7.
Duplicate. This is a known issue with php. We've discussed it here before. Feel free to search for the issue.
For anyone else wondering why this happens:
https://github.com/laravel/framework/commit/866a8cfc58430830069bd24feacf2d81e99385a2#commitcomment-9767647
Is there anyone working on a fix at PHP? I can't rely on the whole .env system if it's going to randomly crap out on me.
Is the only workaround to hard-code values into config files right now?
Another workaround is to use php artisan config:cache
for your production
environment.
The artisan command didn't work for me. The same behavior still happens.
The artisan command didn't work for me. The same behavior still happens.
You mean dd(env('APP_ENV'));
behaviour? Obviously that expected which why I said _"for your production
environment"_. https://github.com/laravel/framework/blob/5.0/src/Illuminate/Foundation/Bootstrap/DetectEnvironment.php#L28
So to be clear:
1) In, say, /app/config/app.php add:
'env' => env('APP_ENV')
2) Cache the config files using php artisan config:cache
3) Instead of calling env('APP_ENV');
use \Config::get('app.env');
to avoid the issue.
4) Use config:cache
for every deployment.
This is like death by 1001 papercuts, just one more thing to worry about. Why was this feature added before
the PHP bug was fixed? I don't get it...
I don't get why would you need to cache APP_ENV
, you cache other value such as DB_USERNAME
, QUEUE_DRIVER
etc. This way your app remain working all the time as this code is already resolved in the cached config.php
.
Why was this feature added
Why not use PHP (just like Laravel 4)?
Well, if that the case, you need a new "duplicate" configuration for your none PHP app, if you want to use Python or Go for some of the background/queue process.
I don't need to, APP_ENV
was just an example. I'm caching other things.
I'm not asking why the feature was added, I'm asking why now
. Why before
the PHP bug is fixed?
Hey @tylercubell,
Is there any news about this issue?
Right now I'm setting the "production values" as default in my config files like: (db_password, *_production_password_)
It is still happening in 5.2 or someone solve the issue?
Thanks.
Hi, I'm encountering the same issue here, no clear solution yet ?
I still try to believe that Laravel is a great framework, having to worry about such
issue is kind of unexpected and displeasing.
Please can the docs be updated, to reflect the requirement to use config:cache?! I just lost a few hours on trying to understand why env() was behaving unpredictably, which seems particularly futile now I discover it's been discussed here a few times.
This is documented in our upgrading guide. If there are any other places you'd like to see this in the docs, we'd be very grateful if you could send a PR please. :)
Thanks for the quick response! So wait, is the docs site in Gitbhub, is that what you mean?
This page https://laravel.com/docs/5.2/configuration#determining-the-current-environment makes it sound like using .env would be a great thing to do, but even in dev I'm seeing it toggle between the values I want and null (where, presumably, default values don't exist)
From reading "Do something with dotenv finally #13906" I understand that there is not a real solution for it on Apache and what you need to do is to run: "php artisan config:cache" in commend. I think it's a MUST part in starting laravel project docs.
Thank you @GrahamCampbell for sharing with us the commend.
same issue with me
upgrade my php to 7.0.10 function env get null value
This is a known issue with PHP. Make sure you run php artisan config:cache
and never read env variables from outside the config files.
run php artisan config:clear
will fix the env null value drama
Not clear, but cache.
Hi,
when calling Config::get('app.env'); I'm still getting local, although I changed the env to production.
env(APP_ENV) returns null.
I'm using a thread safe php installation. Do I need to get the unsafe version?
PS: Workaround - get App:environment() from within App and pass it to the view
php artisan config:cache
works for me on Windows 10, PHP 5.6, Apache 2.4.
Is this bug for PHP, Windows or Apache?
Hi @Decadence ,
It is not a PHP/Windows/Apache BUG, it is a ".env" known bug which can be solved with:
php artisan config:cache
as you said.
Good luck.
I am facing the same issue. And the sad part is, php artisan config:cache
can't fix the issue. In my development environment(Mac OS sierra, php 7.0.12, laravel 5.3) if works fine, but in my production server(Ubuntu 14.04.4, php 7.0.11, laravel 5.3), it is not working. Any solution?
@milon
yes... try to do
php artisan config:cache
It will do php artisan cache:clear
automatically.
@llioor php artisan config:cache
first calls the config:clear
commad.
public function fire()
{
$this->call('config:clear');
$config = $this->getFreshConfiguration();
$this->files->put(
$this->laravel->getCachedConfigPath(), '<?php return '.var_export($config, true).';'.PHP_EOL
);
$this->info('Configuration cached successfully!');
}
Anyway, I tried it as well. No luck.
How can I solve this problem with lumen ?
@liuyunzhuge in lumen you have to load the config file in bootstrap/app.php
file like this-
$app->configure('config_file_name');
if you already do that, then comment the line and clear cache. then uncomment it again. I don't know why, but it worked for me.
run this :
php artisan config:clear
I recently had this issue. it was fixed after I restarted the server.
Here is another solution I got from S.O
php artisan config:clear did the trick.
php artisan config:clear
php artisan cache:clear
service apache2 restart (just in case)
http://stackoverflow.com/questions/39046560/laravel-5-2-envapp-env-does-not-work-in-production
What we should do if we are trying to use env()
outside the config files?
In my middleware I have something like this:
public function handle($request, Closure $next)
{
if($request->header('api-token') != env('WATAPE_KEY')){
abort(400);
}
return $next($request);
}
Should I add my custom variables inside of a config file somehow and then call them with another function that is not env()
?
UPDATE:
Yes, that solves the problem.
I created config/watape.php
<?php
return [
'api_key' => env('WATAPE_KEY'),
];
and now my middleware looks like this:
public function handle($request, Closure $next)
{
if($request->header('api-token') != config('watape.api_key')){
abort(400);
}
return $next($request);
}
Finally clear your cache and rebuild it again. I find this cleaner than calling directly env()
As someone not using laravel that often, it would have been nice for the first comment to mention how you should never use env variables directly and instead reference them in config files.
You should avoid calling env()
in your application. In some environments like testing, the env()
function returns null. A good practice on laravel is to put variables in a config file and to use config()
function instead of env()
https://laravel.com/docs/5.4/configuration#configuration-caching. You can also cache your config files with php artisan config:cache
to speed up your application.
I ran into this issue when configuring Monolog in bootstrap/app.php. I was wanting to use different logging configurations depending on APP_ENV. Is there a recommended way to do this? Can Monolog be configured further down the line once APP_ENV is available to check?
don't use php artisan serve
What you can do is (re)load the .env
content. This will allow you to have access even during production and with your cached config file.
echo 'APP_NAME='.env('APP_NAME').PHP_EOL; // outputs `null`
with(new \Dotenv\Dotenv(base_path()))->load();
echo 'APP_NAME='.env('APP_NAME').PHP_EOL; // outputs your APP_NAME
Doing php artisan config:cache
is the way to go in production, however this was bugging me a lot in local development, and thus I came up with a way to patch it.
app/Http/Kernel.php
protected function bootstrappers()
{
// Remove original LoadEnvironmentVariables bootstrapper and prepend our custom version.
return array_merge([
\App\Library\Core\LoadEnvironmentVariables::class,
], array_diff($this->bootstrappers, [
\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
]));
}
app/Library/Core/LoadEnvironmentVariables.php
namespace App\Library\Core;
use Dotenv\Dotenv;
use Dotenv\Exception\InvalidPathException;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables as OriginalLoadEnvironmentVariables;
class LoadEnvironmentVariables extends OriginalLoadEnvironmentVariables
{
public function bootstrap(Application $app)
{
if ($app->configurationIsCached()) {
return;
}
$this->checkForSpecificEnvironmentFile($app);
try {
(new Dotenv($app->environmentPath(), $app->environmentFile()))->overload();
} catch (InvalidPathException $e) {
//
}
}
}
app/Library/Utilities/helpers.php
function get_env($key, $default = null)
{
// First try to obtain value from superglobals and only if that fails fall back to getenv.
if (array_key_exists($key, $_ENV)) {
$value = $_ENV[$key];
}
else if (array_key_exists($key, $_SERVER)) {
$value = $_SERVER[$key];
}
else {
$value = getenv($key);
}
// If variable does not exist return default value.
if ($value === false) {
return value($default);
}
// Finally parse and return the value.
switch (strtolower($value)) {
case 'true':
case '(true)':
return true;
case 'false':
case '(false)':
return false;
case 'empty':
case '(empty)':
return '';
case 'null':
case '(null)':
return;
}
if (strlen($value) > 1 && Str::startsWith($value, '"') && Str::endsWith($value, '"')) {
return substr($value, 1, -1);
}
return $value;
}
Then it is all about replacing default env
helper with our brand new get_env
.
It's good enough for my needs. I used it for some time now and haven't had any problems with env since. It works on my local dev machine on windows, but staging server didn't complain either.
@GrahamCampbell do you think it is worth a pr? Of course if problem remains, last checked on 5.4
.
It's now been over two years and nothing has changed. I think this whole environment variable issue is representative of Laravel and its official packages (especially Cashier and Spark). It looks elegant at first glance but when you scratch the surface you find these types of ridiculous design decisions.
Why can't Laravel simply parse environment variables from a text file by itself? Why does it rely on an over-engineered solution that produces unstable results? I'm sorry but this is just plain stupid. Let the minority of users who care about server-level environment variables and understand the caveats opt-in instead of causing problems for the rest of us. Problem solved.
Cost > Benefit. You can clearly see that by all the StackOverflow questions and comments on this thread by now.
@imbrish did you try to clear the cache? php artisan cache:clear
On development, you should avoid using php artisan config:cache
.
@brexis how does it help to solve the env problem?
This is a shame for laravel, nobody giving a clear solution only clear and config cache suggestions
@alsilva86 what's wrong with this solution?
php artisan config:cache
It will clear your old config and then will re-cache it.
Yes, to a lot of you who couldnt understand Let me give you this tip, when
editing /var/www/html/app/config.php
'key' =>
env('APP_KEY','base64:qIaPsvTOUeK2RCOmEjG4xGr2YkeRz84HjXy9uXQ65cY='),
'cipher' => 'AES-256-CBC',
Dont use just the key. Its a Key, value field
2017-12-12 11:09 GMT-02:00 llioor notifications@github.com:
@alsilva86 https://github.com/alsilva86 what's wrong with this solution?
php artisan config:cache
It will clear your old config and then will re-cache it.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/laravel/framework/issues/8191#issuecomment-351046494,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ALM6UwfE0OPE-LEZkLRokYelfHjR8Jloks5s_nsKgaJpZM4D1kgJ
.
--
Andre Luiz / IT and Trading
[email protected] / +55 11 984129269
[image: Linkedin] http://br.linkedin.com/in/bahuan[image: skype]
http://alosilva86
@llioor what's wrong with this solution? that doesn't apply at all to lumen, where this is happening too, we can't do config:cache or something else like that
The only thing that worked for me (on production) was
php artisan config:clear
@iamvinny you seem to be talking about cached config not being updated when .env file is changed, then config:clear
will help. But because of other issues you should keep you config cached in production, thus it's better to do config:cache
which will clear and re-cache the config.
However many here experience different problem - when config is not cached multiple concurrent requests may cause env variables to be blank for some of these requests.
run php artisan config:clear if you don't want to use the config cache else
use run php artisan config:cache
Code from vlucas/phpdotenv repository
$dotenv = new \Dotenv\Dotenv("/var/www/html/", '.env');
$dotenv->load();
If I load my local .env file with this method my code is worked.
After remove this line my code is getting an error, because env function is not working propaply.
You need to specify this in boot function on laravel. You can create a middleware function with:
php artisan make:middleware LoadEnv
and after that you need to add the code to handle
method.
Or you can use the AppBefore middleware's handle
method.
Finished code is
<?php
namespace App\Http\Middleware;
use Closure;
class LoadEnv
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$dotenv = new \Dotenv\Dotenv("/var/www/html/", '.env');
$dotenv->load();
return $next($request);
}
}
And you need to add middleware to Http\Kernel.php
file
protected $middleware = [
LoadEnv::class,
dotenv is so garbage.
I still don't understand why you can't just do if (file_exists('env.php'))
and then have those values be an array, which gets called before the actual config files, and maps them accordingly using a helper function. You could even have your own env()
helper function which checks to see if env array values are set and if they are use them, otherwise use the default second parameter.
Why use a library for something that can literally be less than 10 lines of code?
Hi! I had the same problem; when I enable cache (artisan config:cache) the env() helper function does not work. So I have created my own function to parse the .env file and i have replaced every call to env() function by my own function.
I don't know if this is not a good practice but this has resolved my problem.
If you want, i can share my simple code. I only use Dotenv library.
@bionicmaster There is no solution for Lumen right now. The caching solution is good just for Laravel.
I think that manually loading the configuration file is the only option with Lumen.
$app->configure('app');
The solution is to hardcode your production values into the config files and do not use an .env file in production. Dotenv specifically states it is not meant for production environments.
Wrong... the production environment values have to be protected and u can not share them on the git repository. The solution is to cache the env values with php artisan config:cache
@kjdion84
Dude. Take a chill pill. There is a solution to the multi threading problem which, as already stated by others:
env()
in your config files.If you've done it right, then you wouldn't have to come on here and rant so much. Seems to me you aren't deploying or setting up your configs correctly.
Laravel won't even call dotenv if you've got your configs cached correctly.
@garygreen
Caching the config does not resolve the issue, as stated several times in this thread. Only an idiot would use env()
outside of config files. The only non-obtrusive fix to this issue is to simply hardcode your production values into the actual laravel config files so that this only happens in dev/testing, but then you run into the problem of committing sensitive data to VC.
Also, since your response, 3 more references were made to this issue. Clearly still happening, and no amount of condescending "uR jUsT dOiNg iT wRoNg" is going to help resolve the situation.
@kjjdion
I was responding to a guy who was CLEARLY doing it wrong as he had also posted on Reddit (and subsequently got his account banned) then came onto this github issue to rant about how terrible Dotenv & Laravel is, despite the fact that several people have pointed out his error and a fix for it.
If this was still truly a massive issue, there would be hundreds of developers coming here with the same issue and it would of been fixed by now.
With that said, if you can give steps on exactly why config:cache
doesn't work for you, then the community can begin to debug and understand WHY that isn't working - it's not helpful to say it's not working without any details about your setup, PHP version, Laravel version, what your doing, code examples, etc.
There is no solution for Lumen right now. The caching solution is good just for Laravel.
I think that manually loading the configuration file is the only option with Lumen.
$app->configure('app');
@llioor where do you put that call ? In the bootstrap.php file ? In your class making the DB call ?
Thank you!
@P4Thi0ut
I added it to bootstrap/app.php
:
// load config services
$app->configure('app');
$app->configure('services');
$app->configure('geoip');
$app->configure('filesystems');
Laravel 7 is out. This is still an issue. Why does a web framework need server level environment variables when it can simply be done with PHP constants?
Most helpful comment
run
php artisan config:clear
will fix the env null value drama