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();
}
Ответы
Ответ 1
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');
Ответ 2
Если у вас возникли проблемы с созданием переменной APP_ENV, этот код проще:
$dotenv = new Dotenv\Dotenv(__DIR__);
if(file_exists(".env")) {
$dotenv->load();
}
Ответ 3
Также рассмотрел это, мое текущее решение - использовать Lumen way (по состоянию на 6 июня 2016 года), который был предлагается в обсуждении:
try {
(new Dotenv\Dotenv(__DIR__.'/../'))->load();
} catch (Dotenv\Exception\InvalidPathException $e) {
//
}
При необходимости вы можете выполнить некоторую дополнительную обработку исключений (например, упасть до значений по умолчанию или выполнить некоторую проверку.