Search code examples
laravellumenphpdotenv

Laravel (vlucas/phpdotenv) changing env values dynamically


In my test cases, I try to change some of the environment variables to create better test case coverage.

Laravel by default, only support get environment variable by env($key, $default = null), I cannot change the variable.

The Illuminate\Support\Env only supports get, does not support set.

Also, by default Laravel uses vlucas/phpdotenv to managing the environment variable. Most of them are using ImmutableWriter.

Is there any easy way to support dynamically changing environment variables are stored in ImmutableWriter.

Again, the solution is no necessary to (and should not) be implemented in production for security reasons.


Solution

  • PHP 7+ Closure has some interesting features, which can bypass private/protected checks. It is very hacky, however, pretty good for test cases written.

    use Illuminate\Support\Env;
    
    function resetEnvValue($name, $value)
    {
        $environmentRepository = Env::getRepository();
    
        $fn = function () use ($name, $value) {
            $fn = function() use ($name, $value) {
                $this->writer->write($name, $value);
            };
            $fn->call($this->writer);
        };
        $fn->call($environmentRepository);
    }
    
    resetEnvValue('TIMER', 1);
    
    var_dump(env('TIMER')); // int(1)
    
    resetEnvValue('TIMER', 2);
    
    var_dump(env('TIMER')); // int(2)
    

    Please do not use it production environment, the above code is only suitable for testing since it bypasses all the ImmutableWriter protection.