Skip to Content

Terrain 15 — Perf & production

🔍 Renfort : Partie 15.

1. Mémoriser un calcul ⭐⭐

🕹️ Mission : cacher des stats pendant 10 minutes.

✅ Solution

$this->cache->get('stats', function (ItemInterface $i) { $i->expiresAfter(600); return $this->compute(); });

2. Invalider par tag ⭐⭐⭐

🕹️ Mission : invalider le cache d’un prestataire à sa modification.

✅ Solution

Tagger l’entrée ($item->tag(['provider_' . $id])) ; à la modif : $this->cache->invalidateTags(['provider_' . $id]).

3. Cache public dangereux ⭐⭐⭐

🕹️ Mission : pourquoi ne jamais setPublic() sur une réponse d’un utilisateur connecté ?

✅ Solution

Un proxy partagé servirait les données d’un utilisateur à un autre (fuite). Cache public = contenu identique pour tous ; sinon setPrivate().

4. Mesurer avant d’optimiser ⭐⭐

🕹️ Mission : une page est lente. Première chose à regarder ?

✅ Solution

Le profiler (nombre de requêtes SQL) — le goulot n°1 d’une liste est le N+1. Mesurer avant de toucher au code.

5. Worker mode & état ⭐⭐⭐⭐⭐

🕹️ Mission : pourquoi un état dans une propriété de service est-il dangereux en FrankenPHP worker ?

✅ Solution

Le service survit entre requêtes → l’état par requête fuit vers la suivante (fuite de données). Services sans état / ResetInterface.

6. Migration rétrocompatible ⭐⭐⭐⭐

🕹️ Mission : pourquoi une migration cassante casse un déploiement rolling, et le pattern ?

✅ Solution

L’ancien et le nouveau code tournent un instant ensemble ; une colonne supprimée casse l’ancien. Pattern expand/contract : ajouter d’abord, retirer plus tard.

7. Ordre de déploiement ⭐⭐⭐

🕹️ Mission : ordonnez cache:warmup, migrations:migrate, composer install --no-dev, messenger:stop-workers.

✅ Solution

  1. composer install --no-dev → 2. migrations:migrate → 3. cache:warmup → 4. messenger:stop-workers.

8. Health check ⭐⭐⭐

🕹️ Mission : un endpoint /health qui vérifie la base.

✅ Solution

try { $db->executeQuery('SELECT 1'); return $this->json(['status' => 'ok']); } catch (\Throwable) { return $this->json(['status' => 'degraded'], 503); }

9. Multi-tenant : filtre ⭐⭐⭐⭐⭐

🕹️ Mission : comment garantir qu’un tenant ne voie jamais les données d’un autre (base partagée) ?

✅ Solution

Un SQLFilter Doctrine qui ajoute tenant_id = X à toutes les requêtes (automatique), jamais un WHERE manuel oublié. + tests d’isolation.

10. Config prod ⭐⭐

🕹️ Mission : la config impérative en production ?

✅ Solution

APP_ENV=prod, APP_DEBUG=0, profiler inaccessible ; HTTPS + cookies Secure/HttpOnly.


Fin de la Partie 18. Une quinzaine de terrains, ~150 mini-jeux pour ancrer chaque brique. Place aux projets guidés.

Prochaine étape : Partie 19 — Projets guidés.