在 Laravel 5 中设置 ENV 变量的正确方法是什么


What's the correct way to set ENV variables in Laravel 5?

在 laravel 4 中,我们有:

$env = $app->detectEnvironment(array(
    'local' => array('homestead')
));

默认情况下。

但在 laravel 5 中,它更改为:

$env = $app->detectEnvironment(function()
{
    return getenv('APP_ENV') ?: 'production';
});

此外,他们已经排除了 .gitignore 中的 .env.* 行,现在它有:

.env

并添加了文件 .env.example:

APP_ENV=local
APP_KEY=SomeRandomString
DB_USERNAME=homestead
DB_PASSWORD=homestead

那么,如果我有 2 个以上的环境,我现在是否必须在一个 .env 文件中设置所有这些环境? 例如:

APP_ENV=local
DB_PASSWORD=123
APP_ENV=alpha
DB_PASSWORD=456

如果我没有 .env 文件,laravel怎么知道我正在使用什么环境?

你可以和在Laravel 4中完全一样做:

$env = $app->detectEnvironment(array(
    'local' => array('homestead')
));

*.env文件仅用于将不应放入VCS的敏感数据。在拉拉维尔 4 中也是如此

但似乎在最后几天默认检测环境已更改为:

$env = $app->detectEnvironment(function()
{
    return getenv('APP_ENV') ?: 'production';
});

因此,您可以使用PC名称或ENV文件中的设置变量。

如果在主 env 文件中使用基于 ENV 的环境检测(默认情况下.env文件,则需要添加:

APP_ENV=local

当然local这里是本地环境,你可以把它改成productiondev

目前,我看到的最重要的问题是,在进行生产时,您需要记住将此.env文件内容从APP_ENV=local更改为APP_ENV=production,因此在我看来,更好的方法是基于PC名称的旧默认方法。

现在 ENV 文件。如果使用基于 ENV 的环境检测,则应仅将以下内容放入 ENV 文件中:

APP_ENV=local

现在,您可以为不同的环境创建单独的 ENV 文件,例如:

.

local.env

 MY_DB=testdb
.

生产.环境

MY_DB=productiondb

现在bootstrap.environment.php文件中,您可以修改:

if (file_exists(__DIR__.'/../.env'))
{
    Dotenv::load(__DIR__.'/../');
}

到:

if (file_exists(__DIR__.'/../.env'))
{
    Dotenv::load(__DIR__.'/../');
    if (getenv('APP_ENV') && file_exists(__DIR__.'/../.' .getenv('APP_ENV') .'.env')) {
        Dotenv::load(__DIR__ . '/../', '.' . getenv('APP_ENV') . '.env');
    }   
}

根据主环境文件中APP_ENV加载额外的环境文件。

现在,您将能够像往常一样在其他配置文件中使用它:$_ENV['MY_DB']

对于那些刚刚升级到 5.2 的人:

不能再使用静态Dotenv::load()方法。请改用以下内容:

$dotenv = new Dotenv'Dotenv(__DIR__ . '/../', '.' . getenv('APP_ENV') . '.env'); // Laravel 5.2
$dotenv->load();

bootstrap/app.php.

//编辑所以。。在过去的一个小时里深入研究了这个问题之后,我不妨在这里添加一些额外的信息:

  • Laravel使用.env文件进行配置
  • 默认情况下,加载应用程序根目录中的文件".env">
  • 您可以通过env()帮助程序函数或直接通过 PHP 的本机getenv()函数访问这些 .env 文件中的值。尽管您应该只这样做以填充配置文件(请参阅/config/*.php(,因为它们可以缓存。
  • .env 文件在检测环境类中加载。在调试以设置断点时,我发现这很有帮助。请注意(new Dotenv($app->environmentPath(), $app->environmentFile()))->load();行:由于它使用load()因此不会覆盖任何已设置的环境值! (你必须使用overload()来做到这一点 - 这让我发疯,因为 homestead 在 php-fpm 配置/etc/php/7.0/fpm/php-fpm.conf中将APP_ENV变量设置为local,并且您无法通过 .env 文件更改它(
  • 编写单元测试时,通常从 TestCase 继承,它将 APP_ENV 变量设置为 test(通过 refreshApplication() - 使用 putenv() 覆盖默认的 local 值(

我只是想为 Laravel 5.1 贡献我的解决方案,恕我直言,它稍微简单一些。在引导程序/app.php中,我有(就在实例化应用程序之后(:

$app->beforeBootstrapping('Illuminate'Foundation'Bootstrap'DetectEnvironment::class, function() use ($app) {
    $suffix = (env('APP_ENV')) 
        ? '.'.env('APP_ENV') 
        : '';
    $app->loadEnvironmentFrom('.env'.$suffix);
});

无需任何检查或错误处理。如果未找到文件,Laravel将默认为"生产"。

仅此而已。

默认情况下

不能有多个.env文件,并且将其排除在 .gitignore 中,这是有意为之,也是管理环境的预期方法。.env文件不应在版本控制中,应按环境进行配置。 .env设置您的环境和所有环境变量。

因此,如果我有超过 2 个环境,我是否必须设置所有环境 现在在单个 .env 文件中?

不。在安装应用程序的每个位置都有一个.env文件。区别在于该文件中的内容。

此外,由于.env文件只是一个键值存储,因此任何后续声明都将覆盖以前的声明。在您的示例中,Laravel永远不会看到您的"本地"设置。

乍一看似乎很奇怪,但这个新的默认系统实际上通常更容易,并且不太容易出现"4.2 way"所具有/具有的问题,因为没有逻辑错误的地方。

如果我没有 .env 文件,laravel怎么知道我正在使用什么环境?

它根本不会运行。在.env文件中还有一个APP_KEY声明,Laravel不会没有它运行。如果没有.env文件,您将收到 500 服务器错误。

对于 Laravel 版本 10 及更高版本:

您实际上可以使用此软件包syamsoul/laravel-set-env

  1. 只需通过作曲家安装
composer require syamsoul/laravel-set-env
  1. 运行以下命令:
php artisan souldoit:set-env
  • 系统将提示您插入变量名称和值。
  • 或者可以直接将变量名称和值插入到参数中,例如:
php artisan souldoit:set-env "MY_APP_NAME=My Application"