Как правильно установить переменные ENV в Laravel 5?

В laravel 4 у нас было:

$env = $app->detectEnvironment(array(
    'local' => array('homestead')
));

по умолчанию.

Но в laravel 5 он изменился на:

$env = $app->detectEnvironment(function()
{
    return getenv('APP_ENV') ?: 'production';
});

Кроме того, они исключили строку .env.* в .gitignore, теперь она имеет:

.env

И добавил файл .env.example:

APP_ENV=local
APP_KEY=SomeRandomString
DB_USERNAME=homestead
DB_PASSWORD=homestead

Итак, если у меня более двух сред, нужно ли теперь устанавливать их все в одном файле .env? Например.:

APP_ENV=local
DB_PASSWORD=123

APP_ENV=alpha
DB_PASSWORD=456

Если бы у меня не было файла .env, как laravel узнал бы, какую среду я использую?


person Alexander Kim    schedule 13.10.2014    source источник
comment
Привет, Хейхати, в laravel-5, в какой папке находится файл .ENV. Я не могу найти этот файл. Не могли бы вы мне помочь.   -  person Nana Partykar    schedule 04.09.2015


Ответы (4)


Вы можете сделать это точно так же, как в Laravel 4:

$env = $app->detectEnvironment(array(
    'local' => array('homestead')
));

*.env используются только для размещения конфиденциальных данных, которые не следует помещать в VCS. То же самое в Laravel 4

но кажется, что в последние дни по умолчанию значение параметраDetectEnvironment было изменено на:

$env = $app->detectEnvironment(function()
{
    return getenv('APP_ENV') ?: 'production';
});

поэтому вы можете использовать переменную настройки либо из имени ПК, либо из файла ENV.

Если вы используете обнаружение среды на основе ENV в основном файле env (по умолчанию файл .env, вам необходимо добавить:

APP_ENV=local

Конечно, local здесь локальная среда, вы можете изменить ее на production или dev.

На данный момент самая важная проблема, которую я вижу, заключается в том, что вам нужно помнить, когда вы переходите к производству, чтобы изменить содержимое этого файла .env с APP_ENV=local на APP_ENV=production, поэтому, на мой взгляд, гораздо лучшим методом является старый метод по умолчанию, основанный на именах ПК.

Теперь файлы ENV. Если вы используете обнаружение среды на основе ENV, вы должны поместить в свой файл ENV только:

APP_ENV=local

Теперь вы можете создавать отдельные файлы ENV для разных сред, например:

.local.env :

 MY_DB=testdb

.production.env :

MY_DB=productiondb

и теперь в файле bootstrap.environment.php вы можете изменить:

if (file_exists(__DIR__.'/../.env'))
{
    Dotenv::load(__DIR__.'/../');
}

в:

if (file_exists(__DIR__.'/../.env'))
{
    Dotenv::load(__DIR__.'/../');

    if (getenv('APP_ENV') && file_exists(__DIR__.'/../.' .getenv('APP_ENV') .'.env')) {
        Dotenv::load(__DIR__ . '/../', '.' . getenv('APP_ENV') . '.env');
    }   
}

для загрузки дополнительного файла env на основе APP_ENV из основного файла env.

Теперь вы сможете использовать его в другом файле конфигурации, как всегда: $_ENV['MY_DB']

person Marcin Nabiałek    schedule 13.10.2014
comment
Спасибо, без изменения environment.php я могу использовать только один файл .env, верно? также я могу установить APP_ENV только один раз? - person Alexander Kim; 14.10.2014
comment
И я думаю, что этот новый способ более удобен, чем старый. Потому что каждый раз, когда вы развертываете из github/bitbucket, вам придется создавать файл .env с необходимой средой и переменными. - person Alexander Kim; 14.10.2014
comment
@Heihachi Да, по умолчанию он загружает только .env файл, поэтому у вас не может быть 2 ENV с настройками для разных сред. Конечно, если вы можете, одного файла достаточно, если вы будете использовать в своих файлах конфигурации разные имена переменных env для разных сред. - person Marcin Nabiałek; 14.10.2014
comment
Но что, если у нас вообще нет файла .env? Как laravel узнает, какую среду мы используем? Я работаю над локальной виртуальной машиной и печатаю App::environment(); и показывает локально. Как он узнает, что я нахожусь в локальной среде, а не в производстве? - person Alexander Kim; 14.10.2014
comment
@MarcinNabiałek - вам следует обновить свой ответ - я думаю, что в последнем L5 остается только ENV? - person Laurence; 05.11.2014
comment
@TheShiftExchange Я не очень внимательно смотрел на L5, потому что он все еще меняется, но вы правы - что-то могло измениться, но на момент ответа он работал - person Marcin Nabiałek; 05.11.2014
comment
я нашел это же решение с некоторым просмотром. ну, поставьте, и это то, что, я считаю, следует соблюдать на этапе разработки. Я не знаю, почему поддержка была подавлена. - person rolfk; 23.04.2015
comment
@MarcinNabiałek Извините, я не так хорошо знаком с новой структурой фреймворка. Хотел бы спросить, если у меня несколько сред, как и где мне его настроить и попросить систему определить, в какой среде я нахожусь? Раньше, когда я был в L4.2, я делал это таким образом $env = $app->detectEnvironment(array( 'local' => array('homestead'), 'development' => array('develop.example.com'), 'production' => array('example.com'), )); - person Kenny Yap; 21.05.2015
comment
В последней версии L5 (5.1) больше нет файла bootstrap.environment.php. См. ответ Энтони Пиллоса на stackoverflow.com/a/29424899/413531 о том, как заставить его работать в L5. - person Hirnhamster; 22.10.2015

Для тех, кто только что обновился до 5.2:

Вы больше не можете использовать статический метод Dotenv::load(). Вместо этого используйте следующее:

$dotenv = new Dotenv\Dotenv(__DIR__ . '/../', '.' . getenv('APP_ENV') . '.env'); // Laravel 5.2
$dotenv->load();

in bootstrap/app.php.

//edit Soo.. после того, как я копался в этом в течение последнего часа, я мог бы добавить сюда дополнительную информацию:

  • Laravel использует файлы .env для настройки
  • По умолчанию загружается файл ".env" в корневом каталоге приложения.
  • Вы можете получить доступ к значениям в этих файлах .env через вспомогательную функцию env() или напрямую через встроенную функцию PHP getenv(). Хотя вы должны делать это только для заполнения файлов конфигурации (см. /config/*.php), потому что они могут кэшироваться .
  • файлы .env загружаются в DetectEnvironment класс. Я нашел это полезным при отладке для установки точек останова. Обратите внимание на строку (new Dotenv($app->environmentPath(), $app->environmentFile()))->load();: поскольку она использует load() любое значение среды, которое уже было установлено, не будет перезаписано! (Вам пришлось бы использовать overload() для этого - это сводило меня с ума, потому что homestead устанавливает переменную APP_ENV в значение local в конфиге php-fpm /etc/php/7.0/fpm/php-fpm.conf и изменить его через файл .env нельзя)
  • при написании модульных тестов вы обычно наследуете от TestCase, который устанавливает для переменной APP_ENV значение тестирования (через refreshApplication() -- использование putenv() для переопределения значения по умолчанию local)
person Hirnhamster    schedule 17.01.2016
comment
Вы спасли мой день. Мой .env внезапно не загрузился. Мне пришлось изменить ваш код, чтобы заставить его работать на меня: $dotenv = new Dotenv\Dotenv(__DIR__.'/../'); Может ли это стать проблемой в будущем? - person Carsten; 01.02.2016

Я просто хотел предложить свое решение для Laravel 5.1, которое ИМХО немного проще. В bootstrap/app.php у меня есть (сразу после создания приложения):

$app->beforeBootstrapping(\Illuminate\Foundation\Bootstrap\DetectEnvironment::class, function() use ($app) {
    $suffix = (env('APP_ENV')) 
        ? '.'.env('APP_ENV') 
        : '';
    $app->loadEnvironmentFrom('.env'.$suffix);
});

Нет необходимости в какой-либо проверке или обработке ошибок. Laravel по умолчанию будет работать, если файл не найден.

Вот и все.

person thefuzzy0ne    schedule 17.07.2016

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

Итак, если у меня более двух сред, нужно ли теперь устанавливать их все в одном файле .env?

Нет. У вас будет файл .env в каждом месте, где установлено ваше приложение. Разница в том, что находится внутри этого файла.

Кроме того, поскольку файл .env представляет собой просто хранилище ключей и значений, любые последующие объявления будут перезаписывать предыдущие. В вашем примере Laravel никогда не увидит ваши «локальные» настройки.

Поначалу это кажется странным, но эта новая система по умолчанию на самом деле в целом проще и менее подвержена проблемам, которые были у «способа 4.2», поскольку в ней нет места для логических ошибок.

Если бы у меня не было файла .env, как laravel узнал бы, какую среду я использую?

Он бы вообще не запустился. В файле .env также есть объявление APP_KEY, без которого Laravel не запустится. Без файла .env вы получите ошибку сервера 500.

person Shauna    schedule 12.01.2017
comment
Я понимаю логику одного файла .env, но в случае с автоматизированной системой CI все разваливается. Мы используем TravisCI в GitHub, который настраивается и отключается на лету. Без фиксации файла .env в GitHub, как я могу настроить свою среду Travis для просмотра правильной базы данных и т. д.? - person Brandon; 17.05.2017
comment
@Brandon - если вы правильно настроили файлы config.php, то вы можете настроить саму серверную среду, если вы того пожелаете, поэтому вы добавите ее в конфигурацию самой системы CI. Вероятно, вы найдете это обсуждение полезно. Также существует эта методика. - person Shauna; 19.05.2017