Laravel .env
file values are read by Laravel at the application bootstrap time and stored in the PHP $_ENV
global array under the respective keys.
You can change any of those Laravel's (or other $_ENV's) values as simple as:
// Assign the key's new value in the $_ENV global array
$_ENV['DB_CONNECTION'] = 'sqlite';
However if Laravel would take your change into account or not depends on the place in the code where you put this assignment.
Development, Staging, Production Environments:
Changing env values dynamically in memory for these environments is a bad idea.
Nevertheless to make this change you have to put your assignements in the Laravel bootstrap file before the framework instantiates LoadEnvironmentVariables class (for Lumen, the instantiation happens in /bootstrap/app.php
file, for Laravel you could put your changes in the same file before application instantiation).
Testing Environment
However for testing environment changing env variables can be sometimes useful.
On top of the PHPUnit capability to change env variables at the test loading (as an example see the Laravel's phpunit.xml
in your project folder):
<php>
<env name="DB_CONNECTION" value="sqlite"/>
</php>
you can change the variables in the PHPUnit's setUp
function, (that in Laravel also bootstraps the application - note the tests extend the Laravel TestCase
) like the following:
public $savedDBConnection;
public function setUp():void
{
$this->savedDBConnection = $_ENV['DB_CONNECTION'];
$_ENV['DB_CONNECTION'] = 'mysql';
parent::setUp();
}
Caveat
Rather often you may face the unpleasant side effects of such dynamic changes (e.g. you test with in memory database and temporarily switch to on-disk test DB and some other test's database refresh erases your on-disk test DB data).
To avoid this you have to save the variables before you change them in setUp
method (as shown above) and restore them in tearDown
method, like this:
public function tearDown():void
{
$_ENV['DB_CONNECTION'] = $this->savedDBConnection;
parent::tearDown();
}
Alternative
There is the other sometimes more applicable approach to change your .env
variables for testing environment (credits go here.): create the .env.testing
file and load it when in tests. Briefly, add the following colde as explained in the comments
// 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();
}
Now it is enough information to decide whether, when or how one needs / can change the env variables dynamically.