Die Symfony Cache-Komponente
Die Symfony Cache-Komponente
~16 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
Die Dashboard-Statistik aus Kapitel 33/45 (ProjectStatistikService) berechnet BEI JEDEM Seitenaufruf neu, obwohl sich die zugrunde liegenden Daten oft SELTENER ändern – Zeit, das Ergebnis zwischenzuspeichern.
CacheInterface: Symfonys einheitliche Cache-Abstraktion
<?php
declare(strict_types=1);
namespace App\Service;
use App\Entity\Project;
use App\Repository\TaskRepository;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
class ProjectStatistikService
{
public function __construct(
private readonly TaskRepository $taskRepository,
private readonly CacheInterface $cache,
) {
}
public function berechneStatistik(Project $project): array
{
return $this->cache->get(
sprintf('projekt_statistik_%d', $project->getId()),
function (ItemInterface $item) use ($project) {
$item->expiresAfter(300); // 5 Minuten
return $this->berechneStatistikOhneCache($project);
}
);
}
private function berechneStatistikOhneCache(Project $project): array
{
// ... exakt die Berechnung aus Kapitel 33 ...
}
}CacheInterface ist – GENAU wie LoggerInterface oder MailerInterface – ein AUTOWIRED Service (Block 6). get() implementiert das "Cache-Aside"-Muster in EINEM Aufruf: existiert ein Eintrag für diesen Schlüssel bereits, wird er DIREKT zurückgegeben; existiert KEINER (oder ist er abgelaufen), wird das Callback AUSGEFÜHRT, das Ergebnis GESPEICHERT UND zurückgegeben.
expiresAfter() vs. expiresAt()
$item->expiresAfter(300); // relativ: 300 Sekunden ab JETZT
$item->expiresAt(new \DateTimeImmutable('tomorrow')); // absolut: zu einem festen ZeitpunktDen Cache gezielt invalidieren
Ändert sich eine Aufgabe (Kapitel 21), ist der gecachte Statistik-Wert VERALTET – statt auf den 5-Minuten-Ablauf zu warten, invalidieren wir GEZIELT:
// In TaskZuweisungsService (Kapitel 36) oder wo immer Aufgaben geändert werden:
$this->cache->delete(sprintf('projekt_statistik_%d', $project->getId()));Cache-Adapter: dev vs. prod
framework:
cache:
app: cache.adapter.filesystem # Standard: Dateisystem-basiert, funktioniert überall
# Für Produktion mit mehreren Servern besser:
# app: cache.adapter.redis
# default_redis_provider: '%env(REDIS_URL)%'Der Dateisystem-Adapter funktioniert OHNE zusätzliche Infrastruktur, ist aber SERVER-GEBUNDEN – bei MEHREREN Anwendungsservern (Kapitel 48) sieht Server A NICHT den Cache von Server B. Redis (ein separater, gemeinsam genutzter Cache-Dienst) löst das für Multi-Server-Deployments.
Ein Vorgriff auf Kapitel 46: zwei verschiedene Cache-Arten
| Cache-Art | Was sie cached |
|---|---|
| Dieses Kapitel: CacheInterface ("Application Cache") | Cached BELIEBIGE Werte INNERHALB Ihres PHP-Codes – wie unsere Statistik-Berechnung. |
| Kapitel 46: HTTP-Cache | Cached GANZE HTTP-Responses, oft VOR Ihrer Anwendung, sogar OHNE dass PHP überhaupt ausgeführt wird. |
Tipp: Faustregel für Cache-Schlüssel: IMMER alle Werte einbeziehen, die das Ergebnis beeinflussen (hier: $project->getId()) – ein zu GROBER Schlüssel (z. B. nur 'projekt_statistik' für ALLE Projekte) würde Daten VERSCHIEDENER Projekte fälschlich vermischen.