Skip to content
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

.env issue with PHP thread-safe #7354

Closed
bioteck opened this issue Feb 9, 2015 · 10 comments
Closed

.env issue with PHP thread-safe #7354

bioteck opened this issue Feb 9, 2015 · 10 comments

Comments

@bioteck
Copy link
Contributor

bioteck commented Feb 9, 2015

I noticed a problem with functions putenv() and getenv() when PHP is thread-safe: if a URL is called before another is completed, its environment variables will be reset when the first script is finished. It's problematic with ajax requests, or simply if a user opens several links too quickly in new tabs (for example).

You can reproduce this bug by using WampServer, or any other server with PHP thread-safe, and creating two routes in "app/Http/routes.php":

Route::get('test1', function()
{
    sleep(5);

    return 'APP_ENV: '.env('APP_ENV');
});

Route::get('test2', function()
{
    sleep(5);

    return 'APP_ENV: '.env('APP_ENV');
});

Then call "test1", and while it's sleeping, call "test2".
"test1" will display "APP_ENV: local", but "test2" will display "APP_ENV: "

env_var_issue

This problem occurred with getenv(), but $_ENV and $_SERVER are not affected. So it can be resolved by using Dotenv::findEnvironmentVariable(), which uses $_ENV in priority, instead of getenv() in helper env():

$value = Dotenv::findEnvironmentVariable($key);

if ($value === null) return value($default);

The call of Dotenv::makeMutable() is also needed in bootstrapper "DetectEnvironment.php":

try
{
    Dotenv::makeMutable();
    Dotenv::load($app['path.base'], $app->environmentFile());
}
catch (InvalidArgumentException $e)
{
    //
}
@GrahamCampbell
Copy link
Member

Please open an issue on the phpdotenv repo.

@bioteck
Copy link
Contributor Author

bioteck commented Feb 9, 2015

But it's not a phpdotenv issue! It's a PHP issue. However, I open an issue on Laravel because it can be solved in the way I explained. Why ignore my issue while I suggest a solution?

@GrahamCampbell
Copy link
Member

There's nothing we can realistically do about it.

@GrahamCampbell
Copy link
Member

Wait, what? If you've got a solution, then feel free to send a pull. That would be awesome! :)

Issues aren't very helpful to us.

@neomerx
Copy link

neomerx commented Feb 10, 2015

@bioteck Have you noticed? You should choose where to post issues depending on whether you have solution. 👍

@crynobone
Copy link
Member

There's nothing we can realistically do about it.

Change env() to use Dotenv::findEnvironmentVariable($key) instead of getenv($key)?

@GrahamCampbell
Copy link
Member

@crynobone I actually already privately discussed this via email, and it's clear that I was too hastily to dismiss this, but we're very much happy to receive pull requests to address this :)

@fkomaralp
Copy link

fkomaralp commented Apr 28, 2018

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,

@devcircus
Copy link
Contributor

@fkomaralp Laravel automatically calls the load method for you when the framework boots.

pH-7 added a commit to Lifyzer/Food-Scanner-API-Backend that referenced this issue Sep 30, 2021
Let's not use  /  anymore as they are not thread safe.

laravel/framework#7354
@JustinShift
Copy link

If anyone is interested this issues only started happening to us when we set clear_env = yes in the PHP-FPM pool config. We still testing to confirm but thought I would post it here in case it helps somebody else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants