如何在laravel或php中动态更改php dotenv(.env)变量?

时间:2017-01-24 11:57:17

标签: php laravel

我想要这样的事情:

env('APP_ENV');
setenv('APP_ENV', 'testing');
env('APP_ENV');

输出:

staging
testing

我找到一个答案How to change variables in the .env file dynamically in Laravel? 但是这里.env永久保存,我不想永久保存。 phpunit是如何做到这一点的?因为我可以把这个放在phpunit.xml中:

...
<php>
    <env name="APP_ENV" value="testing"/>
</php>
....

并且env(&#39; APP_ENV&#39;)给了我测试&#39; ...

4 个答案:

答案 0 :(得分:2)

putenv()就像魅力一样:

echo env('APP_ENV');
putenv('APP_ENV=testing');
echo env('APP_ENV');

输出:

staging
testing

.env文件未附加...

答案 1 :(得分:1)

在应用程序引导时,Laravel .env文件值are read by Laravel并存储在PHP $_ENV global array中,位于相应键下。

您可以简单地更改任何Laravel(或其他$ _ENV)值:

// Assign the key's new value in the $_ENV global array
$_ENV['DB_CONNECTION'] = 'sqlite';

Laravel是否考虑您的更改取决于您在代码中放置此作业的位置。

开发,登台,生产环境:

在这些环境中动态更改内存中的env值是一个坏主意。

但是,要进行此更改,您必须在框架实例化LoadEnvironmentVariables类之前将分配的内容放入Laravel引导文件中(对于Lumen,实例化发生在/bootstrap/app.php文件中,对于Laravel,您可以将您的在应用程序实例化之前在同一文件中进行更改)。

测试环境

但是对于测试环境,更改环境变量有时会很有用。

the PHPUnit capability顶部更改测试加载时的环境变量(例如,请参阅项目文件夹中的Laravel的phpunit.xml

<php>
    <env name="DB_CONNECTION" value="sqlite"/>
</php>

您可以更改PHPUnit's setUp function中的变量(在Laravel also bootstraps the application中要注意-注意测试扩展了Laravel TestCase),如下所示:

public $savedDBConnection;
public function setUp():void
{
    $this->savedDBConnection = $_ENV['DB_CONNECTION'];
    $_ENV['DB_CONNECTION'] = 'mysql';
    parent::setUp();
}

注意事项

通常,您可能会遇到这种动态更改带来的不愉快的副作用(例如,您在内存数据库中进行测试并暂时切换到磁盘上的测试数据库,而其他一些测试database refresh会擦除磁盘上的测试数据库数据)。

为避免这种情况,您必须先保存变量,然后才能在setUp方法中对其进行更改(如上所示),然后在tearDown method中对其进行还原,如下所示:

public function tearDown():void
{
    $_ENV['DB_CONNECTION'] = $this->savedDBConnection;
    parent::tearDown();
}

现在,有足够的信息来决定是否或何时需要动态更改环境变量。

答案 2 :(得分:0)

Dotenv是不可变的,因此您无法更改已分配的值。 (https://github.com/vlucas/phpdotenv#immutability

PHPUnit在启动laravel之前在引导期间设置此值。 Laravel dotenv在不可变模式下运行,因此已设置的值不会被覆盖。

答案 3 :(得分:0)

注意:

Laravel ~5.7:

env('AAA') = getenv('AAA') → 要设置变量 AAA 的值,只需使用 putenv('AAA', 'true');

→ env('AAA') 将变为真

您可以在此处查看 getenv() 的详细信息 https://github.com/laravel/framework/blob/5.7/src/Illuminate/Support/helpers.php

Laravel 5.8~:

从 Laravel 5.8 开始,env() 不再使用 getenv()。

因此,env('AAA') != getenv('AAA')

→ 所以即使我们使用putenv('AAA', 'true');,env('AAA')的值也不会改变。

因为 env() 的行为变成了

env('AAA') = Env::getRepository()->get('AAA');

→ 要设置变量 AAA 的值,请使用 Env::getRepository()->set('AAA','true') → env('AAA') 将变为 TRUE

你可以在这里查看 Laravel 5.8 的 getenv() 的详细信息 https://github.com/laravel/framework/blob/5.8/src/Illuminate/Support/helpers.php