Laravel 5.1没有使用正确的.env值

时间:2016-09-21 20:34:57

标签: laravel laravel-5.1 laravel-dotenv

我正在使用Laravel 5.1.44,即使我同时使用不同值的.env.testing文件设置,以及App::environment()返回'testing',Laravel似乎仍然只是使用主.env文件中的值。

还有什么我应该仔细检查以确保我没有搞砸或忘记设置某些东西吗?

1 个答案:

答案 0 :(得分:2)

在Laravel 5.2.13之前,无法使用特定于环境的.env文件(例如.env.testing)。即便如此,它只有在您不使用配置缓存时才有效。

最简单的选择是将所有测试特定环境变量添加到phpunit.xml文件中。正如您所提到的那样,您已经在那里找到了一些,添加您需要的任何其他应该没有问题。

如果您真的想要Laravel 5.1中特定于环境的.env文件功能,可以尝试以下操作。请注意,这是未经测试的,只是根据查看源代码的假设。

.env文件加载在名为DetectEnvironment的引导类中。您的想法是创建自己的引导类,修改.env将加载的DetectEnvironment文件的文件名,然后更新Kernel文件,以便调用新的引导类,并在之前打电话 DetectEnvironment bootstrapper。

首先,创建一个新的引导程序类(例如app\Bootstrap\CustomEnvironment.php):

<?php
namespace App\Bootstrap;

use Illuminate\Contracts\Foundation\Application;

class CustomEnvironment
{
    /**
     * Bootstrap the given application.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function bootstrap(Application $app)
    {
        // APP_ENV must already be set.
        // We must know which environment file to look for.
        if (! env('APP_ENV')) {
            return;
        }

        // Build the file name to look for (e.g. .env.testing)
        $file = $app->environmentFile().'.'.env('APP_ENV');

        // If the file exists, set the App to load from that file.
        // The actual loading will take place in DetectEnvironment
        if (file_exists($app->environmentPath().'/'.$file)) {
            $app->loadEnvironmentFrom($file);
        }
    }
}

既然您有一个引导类来更新要加载的.env文件,您需要将其添加到Kernel |以确保在DetectEnvironment之前调用它bootstrap class。

将以下属性添加到app/Console/Kernel.php文件中:

/**
 * The bootstrap classes for the application.
 *
 * @var array
 */
protected $bootstrappers = [
    'App\Bootstrap\CustomEnvironment',
    'Illuminate\Foundation\Bootstrap\DetectEnvironment',
    'Illuminate\Foundation\Bootstrap\LoadConfiguration',
    'Illuminate\Foundation\Bootstrap\ConfigureLogging',
    'Illuminate\Foundation\Bootstrap\HandleExceptions',
    'Illuminate\Foundation\Bootstrap\RegisterFacades',
    'Illuminate\Foundation\Bootstrap\SetRequestForConsole',
    'Illuminate\Foundation\Bootstrap\RegisterProviders',
    'Illuminate\Foundation\Bootstrap\BootProviders',
];

将以下属性添加到app/Http/Kernel.php文件中:

/**
 * The bootstrap classes for the application.
 *
 * @var array
 */
protected $bootstrappers = [
    'App\Bootstrap\CustomEnvironment',
    'Illuminate\Foundation\Bootstrap\DetectEnvironment',
    'Illuminate\Foundation\Bootstrap\LoadConfiguration',
    'Illuminate\Foundation\Bootstrap\ConfigureLogging',
    'Illuminate\Foundation\Bootstrap\HandleExceptions',
    'Illuminate\Foundation\Bootstrap\RegisterFacades',
    'Illuminate\Foundation\Bootstrap\RegisterProviders',
    'Illuminate\Foundation\Bootstrap\BootProviders',
];

注意,乍一看它们看起来很相似,但ConsoleHttp内核之间的引导程序不同(Console还有一个引导程序)。不要复制上述其中一项并将其添加到两个文件中。

修改

另一种更简单的方法是为DetectEnvironment引导程序设置一个before侦听器,并将该文件设置为在事件闭包中加载。

因此,例如,在bootstrap\app.php文件中,在return $app;语句之前添加以下代码:

$app->beforeBootstrapping(
    'Illuminate\Foundation\Bootstrap\DetectEnvironment',
    function($app) {
        // APP_ENV must already be set.
        // We must know which environment file to look for.
        if (! env('APP_ENV')) {
            return;
        }

        // Build the file name to look for (e.g. .env.testing)
        $file = $app->environmentFile().'.'.env('APP_ENV');

        // If the file exists, set the App to load from that file.
        // The actual loading will take place in DetectEnvironment
        if (file_exists($app->environmentPath().'/'.$file)) {
            $app->loadEnvironmentFrom($file);
        }
    }
);

使用beforeBootstrapping()方法,第二个参数中的Closure将在调用第一个参数中的引导程序之前立即执行。现在你不必担心内核或额外的类或任何东西。