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

dly7yett  于 2023-05-30  发布在  PHP
关注(0)|答案(5)|浏览(163)

我想要这样的东西:

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('APP_ENV')给了我'testing'...

s8vozzvw

s8vozzvw1#

putenv()工作起来很有魅力:

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

输出:

staging
testing

.env文件未附加...

1aaf6o9v

1aaf6o9v2#

Laravel .env文件值由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,您可以在应用程序示例化之前将更改放在同一个文件中)。

测试环境

但是,对于测试环境,更改env变量有时会很有用。
除了PHPUnit在测试加载时更改env变量的功能之外(例如,请参阅项目文件夹中的Laravel的phpunit.xml):

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

你可以改变PHPUnit的setUp函数中的变量,(在Laravel also bootstraps the application中-注意测试扩展了Laravel TestCase)如下:

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

注意事项

你可能经常会面对这种动态变化的不愉快的副作用(例如,你可能会遇到一些不愉快的事情)。你用内存中的数据库进行测试,并临时切换到磁盘上的测试数据库,而其他一些测试的数据库刷新会擦除你的磁盘上的测试数据库数据)。
为了避免这种情况,您必须在setUp方法中更改变量之前保存它们(如上所示),并在tearDown方法中恢复它们,如下所示:

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

备选

还有另一种有时更适用的方法来更改测试环境的.env变量(学分转到here。):创建.env.testing文件并在测试时加载它。简单地说,按照注解中的解释添加以下colde

// Add in tests/TestCase.php::createApplication() method
// below $app = require __DIR__.'/../bootstrap/app.php' call.
if (file_exists(dirname(__DIR__) . '/.env.testing')) {
    (new \Dotenv\Dotenv(dirname(__DIR__), '.env.testing'))->load();
}

现在有足够的信息来决定是否、何时或如何动态地更改env变量。

zqdjd7g9

zqdjd7g93#

Dotenv是不可变的,所以你不能改变已经赋值的值。(https://github.com/vlucas/phpdotenv#immutability)
PHPUnit在启动laravel之前的bootstrap期间设置此值。Laravel dotenv运行在不可变模式下,因此已经设置的值不会被覆盖。

h79rfbju

h79rfbju4#

注意事项:

Laravel ~5.7:

env('AAA') = getenv('AAA') →要设置变量AAA的值,只需使用putenv('AAA', 'true');
→ env('AAA')将变为TRUE
您可以在这里查看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

czq61nw1

czq61nw15#

考虑到laravel时不时地在env()助手周围捣乱,简单地使用getenv()而不是env()更容易。然后应该可以使用putenv()随时设置env var。

相关问题