php dotenv 在生产环境中需要 .env 文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30645324/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 21:56:07  来源:igfitidea点击:

dotenv requires .env file on production

phpenvironment-variablesproduction-environmentphpdotenv

提问by Sander Visser

I'm using dotenv for PHP to manage the environment settings (not lavarel but I tagged it because lavarel also uses dotenv)

我使用 dotenv for PHP 来管理环境设置(不是 lavarel,但我标记了它,因为 lavarel 也使用 dotenv)

I have excluded the .env from the code base and I have added the .env.example for all other collaborators

我已经从代码库中排除了 .env 并为所有其他合作者添加了 .env.example

On the github page of dotenv:

在dotenv的github页面上:

phpdotenv is made for development environments, and generally should not be used in production. In production, the actual environment variables should be set so that there is no overhead of loading the .env file on each request. This can be achieved via an automated deployment process with tools like Vagrant, chef, or Puppet, or can be set manually with cloud hosts like Pagodabox and Heroku.

phpdotenv 是为开发环境制作的,一般不应用于生产环境。在生产中,应该设置实际的环境变量,以便在每个请求上加载 .env 文件时没有开销。这可以通过使用 Vagrant、Chef 或 Puppet 等工具的自动化部署过程来实现,也可以使用 Pagodabox 和 Heroku 等云主机手动设置。

The thing that I don't understand is that I get the following exception:

我不明白的是我得到以下异常:

PHP Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Dotenv: Environment file .env not found or not readable.

PHP Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Dotenv: Environment file .env not found or not readable.

This contradicts with what documentation says "the actual environment variables should be set so that there is no overhead of loading the .env file on each request."

这与文档中所说的“应该设置实际的环境变量,以便没有在每个请求上加载 .env 文件的开销”相矛盾。

So the question is if there's any reason why dotenv throws that exception and/or am I missing something? First of all the behavior is different compared to other dotenv libraries (ruby)

所以问题是 dotenv 是否有任何原因抛出该异常和/或我是否遗漏了什么?首先,与其他 dotenv 库(ruby)相比,行为是不同的

I can easily work around this, the not so nice solution:

我可以轻松解决这个问题,不太好的解决方案:

if(getenv('APPLICATION_ENV') !== 'production') { /* or staging */
    $dotenv = new Dotenv\Dotenv(__DIR__);
    $dotenv->load();
}

Nicest solution in my opinion, but I think dotenv should handle this.

我认为最好的解决方案,但我认为 dotenv 应该处理这个问题。

$dotenv = new Dotenv\Dotenv(__DIR__);
//Check if file exists the same way as dotenv does it
//See classes DotEnv\DotEnv and DotEnv\Loader
//$filePath = $dotenv->getFilePath(__DIR__); 
//This method is protected so extract code from method (see below)

$filePath = rtrim(__DIR__, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR . '.env';
//both calls are cached so (almost) no performance loss
if(is_file($filePath) && is_readable($filePath)) {
    $dotenv->load();
}

回答by Alik

Dotenv was built around an idea, that it will be used in development environments only. Thus, it always expects .envfile to be present.

Dotenv 是围绕一个想法构建的,即它只会在开发环境中使用。因此,它总是期望.env文件存在。

The solution you didn't like is a recommended way to use Dotenv. And it seems, that it won't change in near future. Related discussion in project's issue tracker: https://github.com/vlucas/phpdotenv/issues/63#issuecomment-74561880

您不喜欢的解决方案是使用 Dotenv 的推荐方法。而且看起来,在不久的将来不会改变。项目问题跟踪器中的相关讨论:https: //github.com/vlucas/phpdotenv/issues/63#issuecomment-74561880

Note, that Mark offersthere a good approach for production/staging environments, which skips file loading, but not validation

请注意,Mark为生产/暂存环境提供了一种很好的方法,它跳过文件加载,但不进行验证

$dotenv = new Dotenv\Dotenv();
if(getenv('APP_ENV') === 'development') {
    $dotenv->load(__DIR__);
}
$dotenv->required('OTHER_VAR');

回答by Guillaume Caggia

If you have problem to create an APP_ENV variable, this code is easier :

如果您在创建 APP_ENV 变量时遇到问题,则此代码更简单:

$dotenv = new Dotenv\Dotenv(__DIR__);
if(file_exists(".env")) {
    $dotenv->load();
}

回答by Oliver Adria

Also looked into this, my current solution is to use Lumen's way(as of 6 June 2016) which was suggested in a discussion:

还研究了这一点,我目前的解决方案是使用讨论建议的Lumen 方式(截至 2016 年 6 月 6 日):

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

You can still do some additional exception handling if needed (e.g. fall to default values or do some validation.

如果需要,您仍然可以进行一些额外的异常处理(例如,使用默认值或进行一些验证。