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();
}

8

Решение

Dotenv был основан на идее, что он будет использоваться только в средах разработки. Таким образом, он всегда ожидает .env файл должен присутствовать.

Решение, которое вам не понравилось, является рекомендуемым способом использования Dotenv. И кажется, что это не изменится в ближайшее время. Связанное обсуждение в трекере проблем проекта: https://github.com/vlucas/phpdotenv/issues/63#issuecomment-74561880

Обратите внимание, что марки предложения есть хороший подход для производственных / промежуточных сред, который пропускает загрузку файлов, но не проверяет

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

Другие решения

Если у вас есть проблема с созданием переменной APP_ENV, этот код проще:

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

Также посмотрел на это, мое текущее решение заключается в использовании Путь люмена (по состоянию на 6 июня 2016 года), который был предложил в обсуждении:

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

При необходимости вы все равно можете выполнить дополнительную обработку исключений (например, перейти к значениям по умолчанию или выполнить некоторую проверку.

1
По вопросам рекламы [email protected]