I have a custom CMS that I am writing from scratch in Laravel and want to set env
values i.e. database details, mailer details, general configuration, etc from
Watch out! Not all variables in the laravel .env are stored in the config environment. To overwrite real .env content use simply:
putenv ("CUSTOM_VARIABLE=hero");
To read as usual, env('CUSTOM_VARIABLE') or env('CUSTOM_VARIABLE', 'devault')
NOTE: Depending on which part of your app uses the env setting, you may need to set the variable early by placing it into your index.php or bootstrap.php file. Setting it in your app service provider may be too late for some packages/uses of the env settings.
Tailor Otwell generate the laravel application key and set its value using this code (code modified for example purpose):
$escaped = preg_quote('='.config('broadcasting.default'), '/');
file_put_contents(app()->environmentFilePath(), preg_replace("/^BROADCAST_DRIVER{$escaped}/m", 'BROADCAST_DRIVER='.'pusher',
file_get_contents(app()->environmentFilePath())
));
You can find the code in the key generation class:
Illuminate\Foundation\Console\KeyGenerateCommand
Based on josh's answer. I needed a way to replace the value of a key inside the .env
file.
But unlike josh's answer, I did not want to depend on knowing the current value or the current value being accessible in a config file at all.
Since my goal is to replace values that are used by Laravel Envoy which doesn't use a config file at all but instead uses the .env
file directly.
Here's my take on it:
public function setEnvironmentValue($envKey, $envValue)
{
$envFile = app()->environmentFilePath();
$str = file_get_contents($envFile);
$oldValue = strtok($str, "{$envKey}=");
$str = str_replace("{$envKey}={$oldValue}", "{$envKey}={$envValue}\n", $str);
$fp = fopen($envFile, 'w');
fwrite($fp, $str);
fclose($fp);
}
Usage:
$this->setEnvironmentValue('DEPLOY_SERVER', 'forge@122.11.244.10');
you can use this package https://github.com/ImLiam/laravel-env-set-command
then use Artisan Facade to call artisan commands ex:
Artisan::call('php artisan env:set app_name Example')
Based on totymedli's answer and Oluwafisayo's answer.
I set a little modification to change the .env file, It works too fine in Laravel 5.8, but when after I changed it the .env file was modificated I could see variables did not change after I restart with php artisan serve, so I tried to clear cache and others but I can not see a solution.
public function setEnvironmentValue(array $values)
{
$envFile = app()->environmentFilePath();
$str = file_get_contents($envFile);
$str .= "\r\n";
if (count($values) > 0) {
foreach ($values as $envKey => $envValue) {
$keyPosition = strpos($str, "$envKey=");
$endOfLinePosition = strpos($str, "\n", $keyPosition);
$oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);
if (is_bool($keyPosition) && $keyPosition === false) {
// variable doesnot exist
$str .= "$envKey=$envValue";
$str .= "\r\n";
} else {
// variable exist
$str = str_replace($oldLine, "$envKey=$envValue", $str);
}
}
}
$str = substr($str, 0, -1);
if (!file_put_contents($envFile, $str)) {
return false;
}
app()->loadEnvironmentFrom($envFile);
return true;
}
So it rewrites correctly the .env file with the funtion setEnvironmentValue, but How can Laravel reload the new .env without to restart the system?
I was looking information about that and I found
Artisan::call('cache:clear');
but in local it does not work! for me, but when I uploaded the code and test in my serve it works to fine.
I tested it in Larave 5.8 and worked in my serve...
This could be a tip when you have a variable with more than one word and separetly with a space, the solution i did
public function update($variable, $value)
{
if ($variable == "APP_NAME" || $variable == "MAIL_FROM_NAME") {
$value = "\"$value\"";
}
$values = array(
$variable=>$value
);
$this->setEnvironmentValue($values);
Artisan::call('config:clear');
return true;
}
Since Laravel uses config files to access and store .env
data, you can set this data on the fly with config()
method:
config(['database.connections.mysql.host' => '127.0.0.1']);
To get this data use config()
:
config('database.connections.mysql.host')
To set configuration values at runtime, pass an array to the
config
helper
https://laravel.com/docs/5.3/configuration#accessing-configuration-values