-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
replacing getenv($key) with array_get($_ENV, $key) #8187
Conversation
I've experienced a related problem as well. However, in my case Dotenv being mutable would impact unit tests, and also environment setups in load balanced clusters (where you might override .env with local environment variables.) So, that's not a solution indeed. In my case, it seemed to be the opposite problem - $_ENV was only empty for the first of two successive http requests. Luckily, it was consistently reproducible. If there's some overlap problem, perhaps this was on the other end of it. It's sounding like this is possibly a bug in php itself. |
They should fix the issue then. |
This pull requests probably overall makes the situation worse. |
Why not $value = array_get($_ENV, $key, getenv($key)); |
@crynobone good solution 👍 |
I'm facing this issue on Linux AMI - AWS |
This shouldn't happen with cli, I think. Are you using it in Apache as cgi or a module? Which mpm are you using (prefork, worker, etc. - if you don't know, I don't believe we've experienced it with php-fpm. |
@toddbc : apache using as module, Server MPM: event |
That's probably why. Env vars are traditionally per-process, so putenv/getenv are not really "thread safe" when you have separate collections. The winnt and event mpms are both multithreaded rather than multiprocess. So basically the issue is that use of Dotenv, given that it modifies the environment using That would imply that changing Dotenv to not use Also, I'm not sure what functions PHP uses to set the environment. They're not all threadsafe or re-entrant in Linux, for example, iirc. |
I've created an issue under Dotenv - vlucas/phpdotenv#76. Depending on your position, this is a PHP bug (what are they supposed to do?), but I'd say as above that modifying the environment in the first place is just a bad idea. If Dotenv changes (not sure if it will), Laravel would also have to change (and this pull request would be correct, I suppose.) |
I tried the @crynobone 's code but it did not work for me. While debugging, I found out that in my case when things break down for concurrent requests, the $key cannot be found nor in getenv(), nor in $_ENV and not even in $_SERVER.
then modified setEnvironmentVariable adding the following block right after list($name, $value) ...
and then in findEnvironmentVariable I added
and call Dotenv::findEnvironmentVariable($key) everywhere where you would normally call getenv() (for example, in Laravel's helpers.php env() function, and replacing 'false' check with 'null' check). Although Dotenv was not meant for production, I don't want to change our deployment and configuration workflow. With my workaround I was able to run apache bench and also concurrent AJAX requests (queued with setInterval() ) for an hour and did not get any issues with Dotenv (before my fixes, I had about one crash each minute). So, now it seems Dotenv's findEnvironmentVariable() is more reliable than PHP's getenv(). |
I've created an issue about creating an read-only mode, without |
Now with the latest Laravel and Dotenv my fix doesn't work anymore because Laravel vendor/laravel/framework/src/Illuminate/Foundation/helpers.php file:
Although hacky, but still it seems logical, considering that Dotenv puts variables in all three locations:
However, for production now I'm using the Laravel's recommended approach (since 5.2) with config:cache and no |
@progmars so "php artisan config:cache" gets rid of the thread safety issues? |
Additional to |
We've been having some issues on some local Windows environments with the new dotenv library.
When you make rapid, successive AJAX requests to a Laravel app, some of the later requests in this chain seem to carry over
putenv()
values from a previous request, but only until the previous request is finished. This sounds strange, I know, but maybe a diagram can help:When
finishes
happens, PHP clears the values that were set usingputenv()
, but this appears to be affecting values across multiple requests from the same session.Debugging
Dotenv
shows us that in the second request, it gets here and the environment variable is found...but only when you ask for it fromgetenv()
. It's not available in$_ENV
or$_SERVER
. Then as the first request dies, it seems to clear out the values previously stored viaputenv()
. I'm not an expert on the PHP innards in Windows, but I suspect this is a bug related to sharing environment data between requests from the same session.So the reason I'm creating this issue here is because Laravel's
env()
helper usesgetenv()
. Unfortunately in our environment, by the time the second request gets there, it's already been unset from the first request. We can tellDotenv
to be mutable, thus ensuring the values get stored in all three environment variable types, but that doesn't help us if Laravel still usesgetenv()
. We could create our ownenv()
helper, but then we won't be able to keep up to date with any changes to Laravel's.This PR represents what I think is a change that won't affect Laravel in any other environments, but will solve this problem in our Windows environment. Any alternate solution is welcome if this one isn't palatable for some reason.