0

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

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

4

1 回答 1

2

在 Laravel 5.2.13 之前,使用环境特定.env文件(例如.env.testing)的能力不可用。即使那样,它也仅在您不使用配置缓存时才有效。

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

如果你真的想要.envLaravel 5.1 中特定于环境的文件功能,你可以尝试以下方法。请注意,这是未经测试的,只是基于查看源代码的假设。

.env文件被加载到一个名为DetectEnvironment. 这个想法是您创建自己的引导类来修改将加载的文件的.env文件名DetectEnvironment,然后更新Kernel文件以便调用新的引导类,并在 DetectEnvironment引导程序之前调用。

因此,首先,创建一个新的引导程序类(例如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|s 以确保它在DetectEnvironment引导类之前被调用。

将以下属性添加到您的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引导程序设置一个之前的侦听器,并将文件设置为在事件闭包中加载。

因此,例如,在您的文件中,在语句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()方法,第二个参数中的闭包将在第一个参数中的引导程序被调用之前立即执行。现在您不必担心内核或额外的类或任何东西。

于 2016-09-22T16:13:13.637 回答