Acabo de comenzar un nuevo proyecto de Symfony 5 (solo trabajé en Symfony 3 antes) y me cuesta entender cómo funcionan juntos los valores en .env y .env.local .
Los documentos de Symfony dicen que los valores en .env.local los valores de .env :
Si necesita anular un valor de entorno (por ejemplo, a un valor diferente en su máquina local), puede hacerlo en un archivo .env.local:
Todas las máquinas en las que estoy trabajando usan la misma configuración básica (mismo servidor de base de datos, etc.) pero algunos valores son diferentes (nombre de base de datos, contraseña, etc.). Por lo tanto, quería poner la configuración común en .env y los valores específicos del dispositivo en .env.local :
# .env ... DB_SERVER="localhost" DB_VERSION="10.4" DB_USER=${DB_DBNAME} DATABASE_URL="mysql://${DB_USER}:${DB_PASS}@${DB_SERVER}/${DB_DBNAME}?serverVersion=${DB_VERSION}" # .env.local DB_DBNAME="someDB" DB_PASS="secretPW" Cuando uso esta configuración, aparece un error y php bin/console debug:container --env-vars muestra DATABASE_URL "mysql://:@localhost/?serverVersion=10.4" . Obviamente, DATABASE_URL se construye ignorando los valores de .env.local .
Puedo resolver esto fácilmente moviendo DATABASE_URL="mysql://... a .env.local pero ¿es esta la forma prevista de usar .env y .env.local ?
Pensé que los valores de estos archivos se fusionan donde los valores .env.local anulan los valores .env . ¿No es este el caso? ¿O cometí algún error?
¿Qué variable de entorno de Symfony está disponible en qué archivo (.env, .env.local, etc.)?
.env se carga antes .env.local y cada archivo se procesa de forma independiente .
Para fines de interpolación, solo las variables de entorno definidas en el mismo archivo, o en un archivo procesado anteriormente , están disponibles durante el procesamiento del archivo .env .
Si bien las variables de entorno definidas en archivos env más específicos superan a las definidas en archivos más generales, en su ejemplo, cuando DB_DBNAME y DB_PASS se sobrescriben o definen demasiado tarde para ser útiles, ya que DATABASE_URL (que depende de ellos) se define antes y no se redefine en el archivo .env.local .
Pero, puedes lograr lo que quieres hacer, solo tienes que hacerlo de una manera diferente.
Primero, cree su variable de entorno DATABASE_URL con marcadores de posición de parámetros , como este:
DATABASE_URL="mysql://%DB_USER%:%DB_PASS%@%DB_SERVER%/%DB_DBNAME%?serverVersion=%DB_VERSION%" Luego, en su archivo services.yaml , defina los parámetros del contenedor para todos estos valores:
# services.yaml parameters: DB_DBNAME: "%env(DB_DBNAME)%" DB_USER: "%env(DB_USER)%" DB_PASS: "%env(DB_PASS)%" DB_SERVER: "%env(DB_SERVER)%" DB_VERSION: "%env(DB_VERSION)%" # rest of your services.yaml file follows Es importante que la configuración de su doctrina se lea así (que es la predeterminada), incluido el bit de resolve :
# doctrine.yaml doctrine: dbal: url: '%env(resolve:DATABASE_URL)%'Con esto obtendrás los resultados deseados.
Creo que el orden es relevante en este caso: como puede ver en el código fuente , .env está completamente cargado y solo después se lee .env.local . Eso significa que configurar las variables de .env.local a una variable de .env parece imposible, mientras que funcionaría al revés.
La documentación también menciona este escollo, junto con un ejemplo:
El orden es importante cuando alguna variable de entorno depende del valor de otras variables de entorno.