13

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

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

在 dotenv 的 github 页面上:

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

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

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

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

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

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

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

我认为最好的解决方案,但我认为 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();
}
4

3 回答 3

13

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

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

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

$dotenv = new Dotenv\Dotenv();
if(getenv('APP_ENV') === 'development') {
    $dotenv->load(__DIR__);
}
$dotenv->required('OTHER_VAR');
于 2015-06-04T15:19:58.373 回答
3

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

$dotenv = new Dotenv\Dotenv(__DIR__);
if(file_exists(".env")) {
    $dotenv->load();
}
于 2016-04-18T20:47:15.373 回答
1

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

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

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

于 2016-06-06T13:48:26.510 回答