hpaknia
hpaknia

Reputation: 3118

Laravel/Lumen 5.3.3: override env values in migrations

In laravel documentations I vividly see:

https://laravel.com/docs/5.3/configuration#environment-configuration

You may also create a .env.testing file. This file will override values from the .env file when running PHPUnit tests or executing Artisan commands with the --env=testing option.

So I suppose by adding a .env.migration file and overriding mysql user credentials, I can run my migrations with another user:

php artisan migrate --env=migration

Well not only it does not override previously defined values, it does not even add new values to environment! In fact artisan command does not load the file at all. I changed the file name to testing, no avail. I updated my composer, still no result.

I have a simple question. What is the best way to handle laravel migrations with another database credentials?

It's also welcomed if I know where is the migration script located in lumen package, so I can start digging into scripts.

Upvotes: 0

Views: 1314

Answers (3)

koorosh safeashrafi
koorosh safeashrafi

Reputation: 309

try this:

try {
    // < L5.8
    // (\Dotenv\Dotenv(dirname(__DIR__,1), '.env')->overload();
    // >= L5.8
    ( \Dotenv\Dotenv::createImmutable( dirname(__DIR__,1).'/.env' ) )->load();
} catch ( \Dotenv\Dotenv\Exception\InvalidPathException $e ) {
    //
}

read this article.

dotEnv repo

Upvotes: -1

Josh
Josh

Reputation: 239

This is a method I use to update specific .env values at runtime (even if the configuration is cached). 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)

$configKey is the key used to access the configuration at runtime (example.. app.log_level (tinker config('app.log_level')).

$newValue is of course the new value you wish to persist.

Upvotes: 0

patricus
patricus

Reputation: 62338

This issue was fixed in 5.3.11 with this PR. If you upgrade to at least that version, artisan commands will respect the --env setting when loading .env files.

If you're using Lumen, you'll need to update your bootstrap/app.php file.

Near the top of the file is this block of code:

try {
    (new Dotenv\Dotenv(__DIR__.'/../'))->load();
} catch (Dotenv\Exception\InvalidPathException $e) {
    //
}

This should be replaced with something like the following:

$suffix = '';

if (php_sapi_name() == 'cli') {
    $input = new Symfony\Component\Console\Input\ArgvInput;

    if ($input->hasParameterOption('--env')) {
        $suffix = '.'.$input->getParameterOption('--env');
    }
} elseif (env('APP_ENV')) {
    $suffix = '.'.env('APP_ENV');
}

$env = '.env';
if ($suffix && file_exists(__DIR__.'/../'.$env.$suffix)) {
    $env .= $suffix;
}

try {
    (new Dotenv\Dotenv(__DIR__.'/../', $env))->load();
} catch (Dotenv\Exception\InvalidPathException $e) {
    //
}

NB: untested, but the idea should work.

Upvotes: 2

Related Questions