Framework: [5.8] Env: No ability to dynamically override env() variables any longer

Created on 27 Feb 2019  路  10Comments  路  Source: laravel/framework

Hi,

So, I'm in the process of upgrading to 5.8, but it appears that since DotEnv was upgraded to 3.3, .env variables are now immutable (making them constants? _this entire change is missing from the upgrade guide, by the way_).

As a result, if I try to override them in my tests (either directly by setting them in the 'new' $_SERVER block, or using putenv), calling them in my implementation using env('key', 'optional-default') no longer works.

Is this a bug, or is there a new, supposed workaround to fix this? The reason I'm asking, is because in my case, I have a couple of unit tests where I need a way to modify these values.

Most helpful comment

Yes, exactly. Most of the suite-wide variables are already placed in the phpunit.xml, or even in a .env.testing file.

As for the config functionality, I can't really use that, as In one of the situations I'm having I'm testing the behaviour of an API connector, and as such I'm overriding an environment-specific URL endpoint. Things I'm testing are (for example) that a specific exception is thrown when a request is made with an unexpected protocol.

All 10 comments

I would have suggest using phpunit.xml.dist but I think you already said for "specific unit tests"? Then it won't work, because the XML file is only for the whole suite/duration of the tests.

But environment variables are not supposed to be changed that way, isn't it rather a configuration value you want to change, simply with config(key, value)?

Yes, exactly. Most of the suite-wide variables are already placed in the phpunit.xml, or even in a .env.testing file.

As for the config functionality, I can't really use that, as In one of the situations I'm having I'm testing the behaviour of an API connector, and as such I'm overriding an environment-specific URL endpoint. Things I'm testing are (for example) that a specific exception is thrown when a request is made with an unexpected protocol.

Hi there,

Looks like this is a question which can be asked on a support channel. Please only use this issue tracker for reporting bugs with the library. If you have a question on how to use functionality provided by this repo you can try one of the following channels:

and as such I'm overriding an environment-specific URL endpoint

Ah, but I think _the solution_ is still to use the config. For that.

Pull in the env endpoint into the config, make your code use the config and in your test, change the config.

At least that is my understanding how this is supposed to be done.

@mfn is right, create something like config/api.php and leverage the config helper to make the changes.

@driesvints Actually it's not a question but a real breaking change!

We have at least to document it.

I had a piece of code to handle DATABASE_URL env var in all my projects which can't work anymore:

<?php
if ($url = env('DATABASE_URL')) {
    $url = parse_url($url);

    if (isset($url['scheme'])) {
        putenv('DB_CONNECTION=' . $url['scheme']);
    }

    if (isset($url['host'])) {
        putenv('DB_HOST=' . $url['host']);
    }

   // ...
}

@mathieutu you aren't suppose to change these env vars at runtime. Please use a config file for that.

I've sent in a PR to the docs for this: https://github.com/laravel/docs/pull/5039

Thanks for the PR, it's perfect!

And actually, this is a function that I'm calling in the database config file.
It updates some other env var, depending of one, and allows Laravel to use a DATABASE_URL env var.

I've planed to make a PR to the framework for that, but I'm not fixed yet about how to handle that properly, and I've not the time to think about it right now.

I've seen that a package is doing quite the same:
https://github.com/itsDamien/laravel-heroku-config-parser

How would you do it instead?

Thanks.

Unfortunately config(['key' => 'newValue']) doesn't work in a Dusk setup (for overriding a config value), and sometimes we really do need to temporarily change an env value for a certain Dusk test.

E.g. set QUEUE_DRIVER=dusk-connection when usually it is 'sync', but in one particular test, I need to check for values in the 'jobs' tables in the DB.

But after I upgraded to 5.8+, now this solution no longer works.

Any ideas for a new workaround?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SachinAgarwal1337 picture SachinAgarwal1337  路  3Comments

ghost picture ghost  路  3Comments

CupOfTea696 picture CupOfTea696  路  3Comments

shopblocks picture shopblocks  路  3Comments

JamborJan picture JamborJan  路  3Comments