PHP kompiliert Quellcode bei jedem Request von Grund auf neu. Dieser Vorgang kostet Zeit und Serverressourcen, besonders bei umfangreichen Anwendungen mit Hunderten von Dateien. PHP OPcache löst dieses Problem, indem es den kompilierten Bytecode im Shared Memory des Servers zwischenspeichert. Nachfolgende Requests greifen direkt auf den fertigen Bytecode zu, ohne den Quellcode erneut parsen und kompilieren zu müssen. Dieses Tutorial erklärt die Funktionsweise von OPcache, zeigt die Aktivierung und Konfiguration in der php.ini und behandelt Best Practices für Entwicklung und Produktion.

Bevor es an Konfiguration und Feintuning geht, lohnt sich ein Blick auf die grundlegende Arbeitsweise des Bytecode-Caches.
Was ist PHP OPcache?
OPcache ist ein Bytecode-Cache, der seit PHP 5.5 fest in den Sprachkern integriert ist. Ohne OPcache durchläuft jede PHP-Datei bei jedem Aufruf drei Schritte: Parsen des Quellcodes, Kompilierung zu Bytecode (auch Opcode genannt) und Ausführung. OPcache überspringt die ersten beiden Schritte, indem es den kompilierten Bytecode im Shared Memory ablegt. Das folgende Diagramm veranschaulicht diesen Ablauf.
flowchart TD
A["HTTP-Request"] --> B{"OPcache aktiv?"}
B -->|"Nein"| C["PHP parst Quellcode"]
B -->|"Ja"| D{"Bytecode im Cache?"}
D -->|"Ja"| E["Bytecode aus Shared Memory laden"]
D -->|"Nein"| C
C --> F["Kompilierung zu Bytecode"]
F --> G["Bytecode im Shared Memory speichern"]
G --> H["Bytecode ausführen"]
E --> H
H --> I["Antwort an Browser"]
Bei aktivem OPcache prüft PHP zuerst, ob der Bytecode einer angeforderten Datei bereits im Cache liegt. Ist das der Fall, wird er direkt aus dem Speicher geladen und ausgeführt. Nur beim allerersten Aufruf findet die vollständige Kompilierung statt.
OPcache aktivieren
Bei den meisten Hosting-Anbietern ist OPcache bereits standardmäßig aktiviert. Die folgende Einstellung in der php.ini schaltet OPcache ein.
<?php
/* php.ini Einstellungen zum Aktivieren */
/* opcache.enable=1 */
/* opcache.enable_cli=0 */
/* OPcache-Status prüfen */
if (function_exists('opcache_get_status')) {
$status = opcache_get_status();
echo "OPcache aktiv: " . ($status['opcache_enabled'] ? 'Ja' : 'Nein');
echo "\nSpeicher belegt: " . round($status['memory_usage']['used_memory'] / 1024 / 1024, 2) . " MB";
echo "\nGecachte Skripte: " . $status['opcache_statistics']['num_cached_scripts'];
}
Die Funktion opcache_get_status() liefert ein assoziatives Array mit allen relevanten Informationen zum aktuellen Zustand des Caches. Im CLI-Modus ist OPcache standardmäßig deaktiviert, da dort kein Shared Memory zwischen Aufrufen geteilt wird.
Die wichtigsten OPcache-Einstellungen
Die Konfiguration von OPcache erfolgt ausschließlich über die php.ini. Die folgenden Einstellungen bestimmen das Verhalten und die Leistung des Caches.
<?php
/* Produktionseinstellungen für die php.ini */
/*
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.interned_strings_buffer=16
*/
/* Aktuelle Konfiguration auslesen */
$config = opcache_get_configuration();
echo "Speicherlimit: " . $config['directives']['opcache.memory_consumption'] . " MB\n";
echo "Max. Dateien: " . $config['directives']['opcache.max_accelerated_files'] . "\n";
echo "Timestamp-Validierung: " . ($config['directives']['opcache.validate_timestamps'] ? 'An' : 'Aus') . "\n";
Die Einstellung opcache.memory_consumption legt den Speicher in Megabyte fest, den OPcache nutzen darf. Bei zu wenig Speicher werden ältere Skripte aus dem Cache verdrängt. Der Wert opcache.max_accelerated_files begrenzt die Anzahl der gecachten Dateien und wird intern auf die nächste Primzahl aufgerundet. Die Einstellung opcache.validate_timestamps steuert, ob OPcache Änderungen an Dateien automatisch erkennt. In der Produktion sollte dieser Wert auf 0 stehen, um maximale Performance zu erreichen.
OPcache leeren und zurücksetzen
Wenn opcache.validate_timestamps auf 0 steht, erkennt OPcache geänderte Dateien nicht automatisch. Nach jedem Deployment muss der Cache daher manuell geleert werden.
<?php
/* Gesamten OPcache leeren */
if (function_exists('opcache_reset')) {
opcache_reset();
echo "OPcache wurde vollständig geleert.\n";
}
/* Einzelne Datei aus dem Cache entfernen */
$datei = '/var/www/html/index.php';
if (function_exists('opcache_invalidate')) {
opcache_invalidate($datei, true);
echo "Datei aus OPcache entfernt: " . $datei . "\n";
}
Die Funktion opcache_reset() leert den gesamten Cache, während opcache_invalidate() gezielt eine einzelne Datei entfernt. Alternativ kann ein Neustart von PHP-FPM den Cache ebenfalls vollständig zurücksetzen. Bei Shared Hosting ohne Shell-Zugang ist opcache_reset() in einem geschützten Skript der empfohlene Weg.
OPcache in der Entwicklung vs. Produktion
Die optimalen Einstellungen unterscheiden sich je nach Einsatzzweck. In der Entwicklung sollen Änderungen sofort sichtbar sein, in der Produktion steht maximale Geschwindigkeit im Vordergrund.
<?php
/* Umgebung erkennen und OPcache-Status anzeigen */
$status = opcache_get_status(false);
$config = opcache_get_configuration();
$validateTimestamps = $config['directives']['opcache.validate_timestamps'];
$umgebung = $validateTimestamps ? 'Entwicklung' : 'Produktion';
echo "Erkannte Umgebung: " . $umgebung . "\n";
echo "Gecachte Dateien: " . $status['opcache_statistics']['num_cached_scripts'] . "\n";
echo "Cache-Treffer: " . $status['opcache_statistics']['hits'] . "\n";
echo "Cache-Fehler: " . $status['opcache_statistics']['misses'] . "\n";
$hitRate = $status['opcache_statistics']['opcache_hit_rate'];
echo "Trefferquote: " . round($hitRate, 2) . "%\n";
In der Entwicklung empfiehlt sich opcache.validate_timestamps=1 zusammen mit opcache.revalidate_freq=0, damit geänderte Dateien bei jedem Request neu geprüft werden. In der Produktion sollte opcache.validate_timestamps=0 gesetzt sein. Dadurch entfällt die Prüfung auf Änderungen komplett und der Bytecode wird ohne Verzögerung aus dem Speicher geladen.
OPcache mit WordPress und Frameworks
CMS wie WordPress und Frameworks wie Laravel oder Symfony profitieren erheblich von OPcache, da sie bei jedem Request viele Dateien laden. Bei WordPress mit zahlreichen Plugins kann opcache.max_accelerated_files auf 20000 oder höher gesetzt werden. Nach Plugin-Updates oder Theme-Änderungen muss der OPcache geleert werden, wenn validate_timestamps deaktiviert ist. Die Funktion opcache_get_status() zeigt unter dem Schlüssel scripts, welche Dateien aktuell im Cache liegen und wie oft sie aufgerufen wurden.
Fazit
PHP OPcache beschleunigt Webanwendungen spürbar, indem es die wiederholte Kompilierung von PHP-Dateien vermeidet. Die Aktivierung erfolgt über opcache.enable=1 in der php.ini. Die wichtigsten Stellschrauben sind opcache.memory_consumption für den verfügbaren Speicher, opcache.max_accelerated_files für die Anzahl gecachter Dateien und opcache.validate_timestamps für die automatische Erkennung von Änderungen. In der Produktion sollte die Timestamp-Validierung deaktiviert sein, um maximale Performance zu erzielen. Nach jedem Deployment muss der Cache dann manuell mit opcache_reset() oder einem PHP-FPM-Neustart geleert werden.