working variable not name docs app php laravel laravel-5 laravel-environment

php - not - ¿Cuál es la forma correcta de establecer variables ENV en Laravel 5?



laravel production mode (5)

El hecho de que no pueda tener más de un archivo .env de forma predeterminada y que esté excluido en .gitignore es intencional y es la forma prevista de administrar los entornos. El archivo .env no debe estar en control de versiones y debe configurarse por entorno. .env establece su entorno y todas las variables de entorno.

Entonces, si tengo más de 2 entornos, ¿tengo que configurarlos todos en un solo archivo .env ahora?

No. Tendría un archivo .env en cada lugar donde tenga instalada su aplicación. La diferencia está en lo que está dentro de ese archivo.

Además, como el archivo .env es simplemente un almacén de clave-valor, cualquier declaración posterior sobrescribiría las anteriores. En su ejemplo, Laravel nunca vería su configuración "local".

Parece extraño al principio, pero este nuevo sistema predeterminado es generalmente más fácil y menos propenso a los problemas que el "4.2 camino" tenía / tiene, ya que no hay lugar para errores de lógica.

Si no tuviera un archivo .env, ¿cómo sabrá laravel qué entorno estoy usando?

No funcionaría en absoluto. En el archivo .env también se encuentra una declaración APP_KEY , que Laravel no ejecutará. Sin un archivo .env , obtendría un error de 500 servidores.

En laravel 4 tuvimos:

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

por defecto.

Pero en laravel 5 ha cambiado a:

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

Además, han excluido la línea .env. * En .gitignore, ahora tiene:

.env

Y archivo agregado .env.example:

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

Entonces, si tengo más de 2 entornos, ¿tengo que configurarlos todos en un solo archivo .env ahora? P.ej:

APP_ENV=local DB_PASSWORD=123 APP_ENV=alpha DB_PASSWORD=456

Si no tuviera un archivo .env, ¿cómo sabrá laravel qué entorno estoy usando?


Para aquellos que acaban de actualizar a 5.2:

Ya no puede usar el Dotenv::load() estático Dotenv::load() . Use lo siguiente en su lugar:

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

en bootstrap/app.php .

// editar Soo ... después de profundizar en esto durante la última hora, también podría agregar algo de información adicional aquí:

  • Laravel usa archivos .env para la configuración
  • De forma predeterminada, se carga el archivo ".env" en el directorio raíz de la aplicación
  • Puede acceder a los valores dentro de esos archivos .env a través de la función auxiliar env() o directamente a través de la función getenv() nativa de PHP. Aunque solo debe hacerlo para completar sus archivos de configuración (consulte /config/*.php ), ya que pueden almacenarse en caché .
  • los archivos .env se cargan en la clase DetectEnvironment . Encontré esto útil durante la depuración para establecer puntos de interrupción. Tome nota de la línea (new Dotenv($app->environmentPath(), $app->environmentFile()))->load(); : ¡Ya que usa load() cualquier valor del entorno que ya haya sido configurado no se sobrescribirá! (Tendría que usar overload() para hacerlo, esto me APP_ENV loco porque homestead establece la variable APP_ENV como local en la configuración php-fpm /etc/php/7.0/fpm/php-fpm.conf y no puede cambiarla a través del archivo .env)
  • cuando escribe pruebas unitarias, generalmente hereda de TestCase , que establece la variable APP_ENV para la prueba (a través de refreshApplication() - usando putenv() para anular el valor local predeterminado)


Puedes hacerlo exactamente igual que en Laravel 4:

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

*.env archivos *.env solo se usan para poner datos confidenciales que no deberían incluirse en VCS. Lo mismo está en Laravel 4

pero parece que en los últimos días el entorno de detección predeterminado se cambió a:

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

para que pueda usar cualquier variable de configuración desde el nombre de la PC o desde el archivo ENV.

Si usa la detección de entorno basado en ENV en el archivo env principal (por defecto, el archivo .env debe agregar:

APP_ENV=local

Por supuesto, aquí es local el entorno local, puede cambiarlo a production o desarrollo

Por el momento, el problema más importante que veo es que debes recordar cuando cambies este contenido del archivo APP_ENV=local de APP_ENV=local a APP_ENV=production por lo que en mi opinión el método predeterminado es el antiguo método predeterminado basado en nombres de PC .

Ahora archivos ENV. Si usa la detección de entorno basado en ENV, debe poner en su archivo ENV únicamente:

APP_ENV=local

Ahora puede crear archivos ENV separados para sus diferentes entornos, por ejemplo:

.local.env :

MY_DB=testdb

.production.env :

MY_DB=productiondb

y ahora en el archivo bootstrap.environment.php puede modificar:

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

dentro:

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

para cargar archivos env adicionales basados ​​en APP_ENV del archivo env principal.

Ahora podrá usarlo en su otro archivo de configuración como siempre: $_ENV[''MY_DB'']


Solo quería aportar mi solución para Laravel 5.1, que es un poco más simple en mi humilde opinión. En bootstrap / app.php, tengo (justo después de la instancia de la aplicación):

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

No hay necesidad de ningún control o manejo de errores. Laravel se ajustará por defecto a "producción" si el archivo no se encuentra.

Eso es todo.