php 如何在运行中以编程方式在 Laravel 中设置 .env 值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40450162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to set .env values in laravel programmatically on the fly
提问by Chintan Palan
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 controller once the user sets up and want to give user the flexibility to change them on the go using the GUI that I am making.
我有一个自定义 CMS,我正在 Laravel 中从头开始编写,并希望env
在用户设置后从控制器设置值,即数据库详细信息、邮件程序详细信息、一般配置等,并希望让用户可以灵活地使用我正在制作的 GUI。
So my question is how do I write the values received from user to the .env
file as an when I need from the controller.
所以我的问题是我如何将从用户接收到的值写入.env
文件作为我需要从控制器接收的值。
And is it a good idea to build the .env
file on the go or is there any other way around it?
.env
随时随地构建文件是个好主意还是有其他方法?
Thanks in advance.
提前致谢。
采纳答案by Oluwafisayo
Based on totymedli's answer.
基于 totymedli 的回答。
Where it is required to change multiple enviroment variable values at once, you could pass an array (key->value). Any key not present previously will be added and a bool is returned so you can test for success.
如果需要一次更改多个环境变量值,您可以传递一个数组 (key->value)。之前不存在的任何键都将被添加并返回一个布尔值,以便您可以测试是否成功。
public function setEnvironmentValue(array $values)
{
$envFile = app()->environmentFilePath();
$str = file_get_contents($envFile);
if (count($values) > 0) {
foreach ($values as $envKey => $envValue) {
$str .= "\n"; // In case the searched variable is in the last line without \n
$keyPosition = strpos($str, "{$envKey}=");
$endOfLinePosition = strpos($str, "\n", $keyPosition);
$oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);
// If key does not exist, add it
if (!$keyPosition || !$endOfLinePosition || !$oldLine) {
$str .= "{$envKey}={$envValue}\n";
} else {
$str = str_replace($oldLine, "{$envKey}={$envValue}", $str);
}
}
}
$str = substr($str, 0, -1);
if (!file_put_contents($envFile, $str)) return false;
return true;
}
回答by Alexey Mezenin
Since Laravel uses config files to access and store .env
data, you can set this data on the fly with config()
method:
由于 Laravel 使用配置文件来访问和存储.env
数据,您可以使用以下config()
方法动态设置这些数据:
config(['database.connections.mysql.host' => '127.0.0.1']);
To get this data use config()
:
要获取此数据,请使用config()
:
config('database.connections.mysql.host')
To set configuration values at runtime, pass an array to the
config
helper
要在运行时设置配置值,请将数组传递给
config
帮助程序
https://laravel.com/docs/5.3/configuration#accessing-configuration-values
https://laravel.com/docs/5.3/configuration#accessing-configuration-values
回答by Oliver Maslo
Watch out! Not all variables in the laravel .env are stored in the config environment. To overwrite real .env content use simply:
小心!并非 laravel .env 中的所有变量都存储在配置环境中。要覆盖真正的 .env 内容,只需使用:
putenv ("CUSTOM_VARIABLE=hero");
putenv ("CUSTOM_VARIABLE=hero");
To read as usual, env('CUSTOM_VARIABLE') or env('CUSTOM_VARIABLE', 'devault')
像往常一样阅读 env('CUSTOM_VARIABLE') 或 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.
注意:根据应用程序的哪个部分使用 env 设置,您可能需要通过将其放入 index.php 或 bootstrap.php 文件来提前设置变量。对于 env 设置的某些包/用途而言,在您的应用服务提供商中设置它可能为时已晚。
回答by vesperknight
Based on josh's answer. I needed a way to replace the value of a key inside the .env
file.
基于乔希的回答。我需要一种方法来替换.env
文件中键的值。
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.
但与 josh 的回答不同,我根本不想依赖于知道当前值或可在配置文件中访问的当前值。
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.
因为我的目标是替换 Laravel Envoy 使用的值,它根本不使用配置文件,而是直接使用该.env
文件。
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', '[email protected]');
回答by Elias Tutungi
More simplified:
更简化:
public function putPermanentEnv($key, $value)
{
$path = app()->environmentFilePath();
$escaped = preg_quote('='.env($key), '/');
file_put_contents($path, preg_replace(
"/^{$key}{$escaped}/m",
"{$key}={$value}",
file_get_contents($path)
));
}
or as helper:
或作为帮手:
if ( ! function_exists('put_permanent_env'))
{
function put_permanent_env($key, $value)
{
$path = app()->environmentFilePath();
$escaped = preg_quote('='.env($key), '/');
file_put_contents($path, preg_replace(
"/^{$key}{$escaped}/m",
"{$key}={$value}",
file_get_contents($path)
));
}
}
回答by Josh
In the event that you want these settings to be persisted to the environment file so they be loaded again later (even if the configuration is cached), you can use a function like this. I'll put the security caveat in there, that calls to a method like this should be gaurded tightly and user input should be sanitized properly.
如果您希望将这些设置持久化到环境文件中,以便稍后再次加载它们(即使配置已缓存),您可以使用这样的功能。我将把安全警告放在那里,对这样的方法的调用应该受到严格的保护,并且应该正确地清理用户输入。
private function setEnvironmentValue($environmentName, $configKey, $newValue) {
file_put_contents(App::environmentFilePath(), str_replace(
$environmentName . '=' . Config::get($configKey),
$environmentName . '=' . $newValue,
file_get_contents(App::environmentFilePath())
));
Config::set($configKey, $newValue);
// Reload the cached config
if (file_exists(App::getCachedConfigPath())) {
Artisan::call("config:cache");
}
}
An example of it's use would be;
它的使用示例是;
$this->setEnvironmentValue('APP_LOG_LEVEL', 'app.log_level', 'debug');
$environmentName
is the key in the environment file (example.. APP_LOG_LEVEL)
$environmentName
是环境文件中的关键(例如..APP_LOG_LEVEL)
$configKey
is the key used to access the configuration at runtime (example.. app.log_level (tinker config('app.log_level')
).
$configKey
是用于在运行时访问配置的键(例如.. app.log_level (tinker config('app.log_level')
))。
$newValue
is of course the new value you wish to persist.
$newValue
当然是你希望保留的新值。
回答by totymedli
tl;dr
tl;博士
Based on vesperknight's answerI created a solution that doesn't use strtok
or env()
.
根据vesperknight 的回答,我创建了一个不使用strtok
或的解决方案env()
。
private function setEnvironmentValue($envKey, $envValue)
{
$envFile = app()->environmentFilePath();
$str = file_get_contents($envFile);
$str .= "\n"; // In case the searched variable is in the last line without \n
$keyPosition = strpos($str, "{$envKey}=");
$endOfLinePosition = strpos($str, PHP_EOL, $keyPosition);
$oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);
$str = str_replace($oldLine, "{$envKey}={$envValue}", $str);
$str = substr($str, 0, -1);
$fp = fopen($envFile, 'w');
fwrite($fp, $str);
fclose($fp);
}
Explanation
解释
This doesn't use strtok
that might not work for some people, or env()
that won't work with double-quoted .env
variables which are evaluated and also interpolates embedded variables
这不使用strtok
它可能对某些人不起作用,或者env()
不适.env
用于评估并插入嵌入变量的双引号变量
KEY="Something with spaces or variables ${KEY2}"
回答by iohan sandoval
Based on totymedli's answer and Oluwafisayo's answer.
基于 totymedli 的回答和 Oluwafisayo 的回答。
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.
我设置了一些修改来更改 .env 文件,它在 Laravel 5.8 中工作得很好,但是当我更改它后 .env 文件被修改时,我可以看到在我用 php artisan serve 重新启动后变量没有改变,所以我试过了清除缓存和其他人,但我看不到解决方案。
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?
所以它使用函数 setEnvironmentValue 正确重写了 .env 文件,但是 Laravel 如何在不重新启动系统的情况下重新加载新的 .env ?
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...
我在 Larave 5.8 中测试了它并在我的服务中工作......
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;
}
回答by Ahmed Atoui
you can use this package https://github.com/ImLiam/laravel-env-set-command
你可以使用这个包 https://github.com/ImLiam/laravel-env-set-command
then use Artisan Facade to call artisan commands ex:
然后使用 Artisan Facade 调用 artisan 命令,例如:
Artisan::call('php artisan env:set app_name Example')
回答by Randy Allen
This solution builds upon the one provided by Elias Tutungi, it accepts multiple value changes and uses a Laravel Collection because foreach's are gross
此解决方案建立在 Elias Tutungi 提供的解决方案之上,它接受多个值更改并使用 Laravel 集合,因为 foreach 很粗糙
function set_environment_value($values = [])
{
$path = app()->environmentFilePath();
collect($values)->map(function ($value, $key) use ($path) {
$escaped = preg_quote('='.env($key), '/');
file_put_contents($path, preg_replace(
"/^{$key}{$escaped}/m",
"{$key}={$value}",
file_get_contents($path)
));
});
return true;
}