Dotenv требует.env файл на производстве
Я использую dotenv для PHP для управления настройками среды (не lavarel, но я пометил его, потому что lavarel также использует dotenv)
Я исключил.env из базы кода и добавил.env.example для всех других соавторов.
На GitHub странице Dotenv:
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();
}
3 ответа
Dotenv был основан на идее, что он будет использоваться только в средах разработки. Таким образом, он всегда ожидает .env
файл должен присутствовать.
Решение, которое вам не понравилось, является рекомендуемым способом использования Dotenv. И кажется, что это не изменится в ближайшем будущем. Связанное обсуждение в трекере проблем проекта: https://github.com/vlucas/phpdotenv/issues/63
Обратите внимание, что Марк предлагает хороший подход для производственных / промежуточных сред, который пропускает загрузку файлов, но не проверяет
$dotenv = new Dotenv\Dotenv();
if(getenv('APP_ENV') === 'development') {
$dotenv->load(__DIR__);
}
$dotenv->required('OTHER_VAR');
Если у вас есть проблема с созданием переменной APP_ENV, этот код проще:
$dotenv = new Dotenv\Dotenv(__DIR__);
if(file_exists(".env")) {
$dotenv->load();
}
Также рассмотрел это, мое текущее решение состоит в том, чтобы использовать способ Люмена (по состоянию на 6 июня 2016 года), который был предложен в ходе обсуждения:
try {
(new Dotenv\Dotenv(__DIR__.'/../'))->load();
} catch (Dotenv\Exception\InvalidPathException $e) {
//
}
При необходимости вы все равно можете выполнить дополнительную обработку исключений (например, перейти к значениям по умолчанию или выполнить некоторую проверку.