Config & .env
Secrets in env files, structure in YAML, parameters in the container. Same lesson as every modern stack - don't scatter
getenvin random classes.
Files you'll touch
| File | Role |
|---|---|
.env | committed defaults / placeholders |
.env.local | your machine overrides (gitignored) |
.env.test | test env |
config/services.yaml | DI defaults, binds, autowire |
config/packages/*.yaml | Flex package config (doctrine, security, …) |
Reading config in PHP
Prefer injecting parameters or typed config services over raw env reads in business code:
yaml
# config/services.yaml (illustrative)
parameters:
app.support_email: '%env(SUPPORT_EMAIL)%'php
<?php
public function __construct(
#[Autowire('%app.support_email%')]
private string $supportEmail,
) {}Exact syntax evolves slightly across versions - when in doubt, copy a Flex recipe pattern from config/packages/.
Env var processors
%env(DATABASE_URL)%, %env(bool:APP_DEBUG)%, %env(int:…)% - cast and validate at boot. Nice when you miss TypeScript parsing env with Zod 😉
Prod habits
APP_ENV=prod+APP_DEBUG=0- Warm cache in deploy:
php bin/console cache:warmup - Never commit real secrets -
.env.local/ vault / platform env
Compared to Laravel
| Laravel | Symfony |
|---|---|
config/*.php + env() | YAML + %env()% |
config('app.name') | parameters / injected values |
.env | .env + .env.local |
As you can see, same separation of "secret vs structure".
Next: testing so refactors don't scare you.
Best,
-- ł.