0

Background:

I tried to write a setup wizard using Laravel 5.5. Some database parameters (database name, user, password) should be written to .env file and then validated. The writing process could be done with this.

Problems I met:

After wrote posted variables into .env file successfully, I tried to reload the variables using code like env('DB_DATABASE'). I found the variables remain unchanged. But after I refreshed the page, the variable will change to correct one. I did check the variables in .env file were already updated before I refresh the page.

What I have tried:

I tried to find a solution. Most solutions refer to use artisan config:clear command. So I put artisan command to my controller like this:

$this->changeEnvironmentVariable('DB_DATABASE',$request->input('db_name'));
$this->changeEnvironmentVariable('DB_USERNAME',$request->input('db_user'));
$this->changeEnvironmentVariable('DB_PASSWORD',$request->input('db_password'));
Artisan::call('config:clear');

But it doesn't work although there are no warnings and errors. The env('DB_DATABASE') still keeps the previous value.

Question:

I could work around this by validating the database information using the posted information instead of load the variables from .env file. However, I just want to know whether there is a way to write and reload .env variables in real-time.

Any comments are appreciated.

Phil
  • 1,444
  • 2
  • 10
  • 21
  • Laravel caches configs to speed up things. You can `php artisan config:cache` in your shell to rewrite the config cache. In your action you should be able to `\Artisan::call('config:cache');` (Whoops, you already do something like that) – brombeer Jan 10 '18 at 14:22

2 Answers2

1

I created a readEnv and changeEnv method to read and write .env file without using env() directly . Which could avoid using the cached data. Hope it could help people who may have similar needs like me.

public function readEnv(){

    $root_dir = realpath(dirname(getcwd()));
    $ini_array = parse_ini_file($root_dir.'\.env', true, INI_SCANNER_RAW);
    $this->env_str[0] = $ini_array['DB_DATABASE'];
    $this->env_str[1] = $ini_array['DB_USERNAME'];
    $this->env_str[2] = $ini_array['DB_PASSWORD'];
    return;

}

public static function changeEnv($key,$value)
{
    $path = base_path('.env');

    if(is_bool(env($key)))
    {
        $old = env($key)? 'true' : 'false';
    }
    elseif(env($key)===null){
        $old = 'null';
    }
    else{
        $old = env($key);
    }

    if (file_exists($path)) {
        file_put_contents($path, str_replace(
            "$key=".$old, "$key=".$value, file_get_contents($path)
        ));
    }
}
Phil
  • 1,444
  • 2
  • 10
  • 21
-1

Your environment write can be successful but without page reloading or go another link this env value will not change. If need to apply this value in current controller or link you can use following lines.

 putenv('DB_DATABASE='.$request->input('db_name'));
 putenv('DB_USERNAME='.$request->input('db_user'));
 putenv('DB_PASSWORD='.$request->input('db_password'));

Now env('DB_DATABASE') will show output of your input value.