Laravel - 自定义 .env 文件

Laravel - custom .env file

Laravel 假设 .env 文件应该描述环境,它不应该提交给你的 repo。

如果我想在我的存储库中保留 devproduction(比如 .env-production.env-dev)的 .env 文件并添加一些应使用哪个文件的自定义逻辑,例如基于当前域名。

类似

if ($_SERVER['HTTP_HOST'] == 'prod.domain.com') {
    load('.env-production');
} else {
    load('.env-dev');
}

我怎样才能实现它? 谢谢!

您已将 .env 文件放入 laravel,您可以定义应用程序的级别。 APP_ENV=local 要么 APP_ENV=production 您可以根据需要设置配置,无需在此处创建新的 .env 文件。有关 Laravel Environment Variables 的更多信息: 以下是对您的更多描述性帮助:phpdotenv

对自定义 .env 文件使用 Dotenv::load()

laravel 5.1 与 vlucas/phpdotenv ~1.0

if ($_SERVER['HTTP_HOST'] == 'prod.domain.com') {
    Dotenv::load(__DIR__ . '/../','.production.env');
} else {
    Dotenv::load(__DIR__ . '/../','.dev.env');
}

laravel 5.2 与 vlucas/phpdotenv ~2.0

$dotenv = new Dotenv\Dotenv(__DIR__, 'myconfig'); // Laravel 5.2
$dotenv->load();

PHP dotenv

在bootstrap/app.php

Nadeem0035 让我很好地知道该怎么做

bootstrap\app.php 就在 return $app;

之前
$envFile = $_SERVER['HTTP_HOST'] == 'prod.domain.com' ? '.env-production' : '.env-dev';
$app->loadEnvironmentFrom($envFile);

我想为那些拥有许多虚拟主机共享代码库的人添加一个解决方案,这些人都需要不同的 .env 文件来处理所有不同的事情,比如 数据库连接、smtp 设置等.

对于 Apache 上的每个 vhost,创建一个 vhost 配置:

<VirtualHost *:80>
    ServerName your-vhost.yourdomain.com
    DocumentRoot /var/www/shared-codebase/public

    SetEnv VHOST_NAME 'your-vhost'

    <Directory "/var/www/shared-codebase/public">
    Options Indexes MultiViews FollowSymLinks
    AllowOverride all
    Order deny,allow
    Require all granted
    </Directory>

    <IfModule mpm_itk_module>
       AssignUserId your-vhost your-vhost
    </IfModule>

    ErrorLog /var/www/your-vhost/logs/error.log
    CustomLog /var/www/your-vhost/logs/access.log combined
</VirtualHost>

所有虚拟主机都具有相同的文档根目录和目录,因为它是共享代码库。在配置中,我们添加了一个 SetEnv VHOST_NAME 'your-vhost',稍后我们将在 Laravel 的 bootstrap.php 中使用它来更改 vhost 特定的位置 .env.

接下来在文件夹中创建自定义 .env file (fe. /var/www/your-vhost/.env) 改变 bootstrap.php 以便它从正确的位置加载 .env。

<?php

$app = new Illuminate\Foundation\Application(
    realpath(__DIR__.'/../')
);

$app->singleton(
    Illuminate\Contracts\Http\Kernel::class,
    App\Http\Kernel::class
);

$app->singleton(
    Illuminate\Contracts\Console\Kernel::class,
    App\Console\Kernel::class
);

$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::class
);

/*
|--------------------------------------------------------------------------
| Add the location of the custom env file
|--------------------------------------------------------------------------
*/    
$app->useEnvironmentPath('/var/www/'.$_SERVER['VHOST_NAME']);

return $app;

就这些了。

[编辑] 如果您想针对特定的数据库或想要为特定的 .env 生成密钥,那么您应该将 VHOST_NAME 放在 artisan 命令的前面。

VHOST_NAME=tenant2.domain.com php artisan key:generate

[编辑] 在本地工作并使用 Laravel Valet 时,您可以在代码库的根目录中添加自定义 .valet-env.phphttps://laravel.com/docs/master/valet#site-specific-environment-variables

我想为在不同机器/主机上工作的团队分享我的两分钱。 我在应用程序的根目录上创建了一个目录 env,其中包含:

  • 一个 .master.env 包含主要和共享配置的文件。
  • 一个 .name 文件只包含一个字符串,其中包含用于特定机器/用途的环境名称(例如 "server1")
  • 与上面定义的名称匹配的特定 .env 文件,例如.server1.env.

然后,在bootstrap/app.php:

/**
 * master config
 */
$app->useEnvironmentPath(__DIR__.'/../env');
$app->loadEnvironmentFrom('.master.env');

/**
 * config overloading
 */
$app->afterLoadingEnvironment(function() use($app) {
    $envFile = trim(file_get_contents($app->environmentPath().'/.name'));
    if ($envFile && file_exists($app->environmentPath().'/.' .$envFile .'.env')) {
        $dotenv = Dotenv\Dotenv::create($app->environmentPath(), '.'.$envFile.'.env');
        $dotenv->overload();
    }
});

现在您可以有选择地覆盖特定机器的配置密钥,如果您没有安全问题,您可以将 env 文件放入 VCS,只要您忽略“.name”文件即可。

在Laravel 5.8工作。

我在开发过程中有类似的要求,想在我的开发箱上做一些临时的 'multitenancy' 来针对多个 databases/configurations 测试相同的代码库。我不想要带有一堆 if/then 语句的意大利面条代码,所以我想出了以下解决方案,它非常适合我的目的(并且不需要对 Apache、nginx 或 Caddy 文件进行任何处理) :

bootstrap/app.php$app = new Illuminate\Foundation\Application(...); 行之后添加以下内容:

// First, check to see if there is a file named '.env'
// within a subdirectory named '.env.{{HOST_NAME}}
//
if (is_file($app->environmentPath().DIRECTORY_SEPARATOR. '.env.' . $_SERVER['HTTP_HOST'] .DIRECTORY_SEPARATOR. '.env')) {

    // ...And if there is, use the directory as the new environment path
    $app->useEnvironmentPath($app->environmentPath().DIRECTORY_SEPARATOR. '.env.'. $_SERVER['HTTP_HOST']);
}ER['HTTP_HOST']);
}

// Otherwise,  just use the standard .env file as the default...

包含此内容后,应用程序仍将默认使用 .env(这意味着您仍然可以为不需要自定义的任何主机使用标准 .env 文件),但是 first 它检查以主机名命名的子目录中是否存在替代 .env 文件(即,如果主机名是 'example.local.com',该文件将驻留在子目录中名为 .env.example.local.com).

您可以更改代码以从目录名称中删除有点多余的 .env. 前缀,但我想添加它以将所有 .env.* 条目保存在目录列表中。

这种方法的一个好处:通过在 子目录中使用通常的名称 ('.env') ,您应该只需要一个条目 .env 以确保 所有 您的自定义配置不在您的 git 存储库中。无需为每个自定义点环境文件添加新的 .gitignore 条目。