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 · 9 comments

Comments

Projects
None yet
6 participants
@bioteck
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

This comment has been minimized.

Show comment
Hide comment
@GrahamCampbell

GrahamCampbell Feb 9, 2015

Member

Please open an issue on the phpdotenv repo.

Member

GrahamCampbell commented Feb 9, 2015

Please open an issue on the phpdotenv repo.

@bioteck

This comment has been minimized.

Show comment
Hide comment
@bioteck

bioteck Feb 9, 2015

Contributor

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?

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@GrahamCampbell

GrahamCampbell Feb 9, 2015

Member

There's nothing we can realistically do about it.

Member

GrahamCampbell commented Feb 9, 2015

There's nothing we can realistically do about it.

@GrahamCampbell

This comment has been minimized.

Show comment
Hide comment
@GrahamCampbell

GrahamCampbell Feb 9, 2015

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.

Member

GrahamCampbell commented Feb 9, 2015

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

This comment has been minimized.

Show comment
Hide comment
@neomerx

neomerx Feb 10, 2015

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

neomerx commented Feb 10, 2015

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

@crynobone

This comment has been minimized.

Show comment
Hide comment
@crynobone

crynobone Feb 10, 2015

Contributor

There's nothing we can realistically do about it.

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

Contributor

crynobone commented Feb 10, 2015

There's nothing we can realistically do about it.

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

@GrahamCampbell

This comment has been minimized.

Show comment
Hide comment
@GrahamCampbell

GrahamCampbell Feb 10, 2015

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 :)

Member

GrahamCampbell commented Feb 10, 2015

@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

This comment has been minimized.

Show comment
Hide comment
@fkomaralp

fkomaralp 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 handlemethod.

Or you can use the AppBefore middleware's handlemethod.
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,

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 handlemethod.

Or you can use the AppBefore middleware's handlemethod.
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

This comment has been minimized.

Show comment
Hide comment
@devcircus

devcircus Apr 28, 2018

Contributor

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

Contributor

devcircus commented Apr 28, 2018

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment