Warenkorb

von 8 Min Lesezeit veröffentlicht 12. September 2026 zuletzt geändert 1. Oktober 2026

OPcache ist entweder an oder aus — so steht es in den meisten Anleitungen, und so melden es die meisten Werkzeuge. Tatsächlich gibt es mindestens fünf Zustände, die von außen gleich aussehen, und nur zwei davon sind ein Fehler der Installation. Die anderen drei sind Entscheidungen des Hosters oder eine Eigenschaft des Kontexts, in dem gerade gemessen wird.

Wer das verwechselt, schreibt Support-Tickets über Zustände, die in Ordnung sind. Oder er hält eine Installation für beschleunigt, die es nicht ist. Dieser Artikel stellt jeden Zustand nach und dokumentiert die Ausgabe, statt sie zu beschreiben.

Kurz gefasst

  • OPcache hat fünf Zustände, die von außen gleich aussehen. Nur zwei davon — nicht installiert und abgeschaltet — sind ein Fehler der Installation.
  • Steht opcache_get_status in disable_functions, meldet jedes Werkzeug „aus“, obwohl OPcache arbeitet. opcache_is_script_cached() beweist das Gegenteil.
  • opcache.restrict_api sperrt die gesamte API: Auch opcache_get_configuration() und opcache_is_script_cached() liefern dann nur eine Warnung und false. Der ehrliche Befund lautet dann „unbekannt“, nicht „aus“.
  • Auf der Kommandozeile ist OPcache standardmäßig aus. Jede Messung über WP-CLI sagt deshalb nichts über die Website.
  • Jeder Zustand am 22. August 2026 unter PHP 8.5 nachgestellt, mit der jeweiligen Ausgabe im Artikel.

Die Sonde

Alles, was ein Werkzeug über OPcache wissen kann, kommt aus vier Quellen: ob die Erweiterung geladen ist, was in den ini-Einstellungen steht, ob die API-Funktionen existieren, und was sie zurückgeben. Die folgende Sonde fragt genau das ab.

<?php
echo "extension_loaded : ", var_export( extension_loaded( 'Zend OPcache' ), true ), "\n";
echo "ini enable       : ", var_export( ini_get( 'opcache.enable' ), true ), "\n";
echo "ini enable_cli   : ", var_export( ini_get( 'opcache.enable_cli' ), true ), "\n";
echo "ini restrict_api : ", var_export( ini_get( 'opcache.restrict_api' ), true ), "\n";
echo "hat get_status   : ", var_export( function_exists( 'opcache_get_status' ), true ), "\n";

if ( function_exists( 'opcache_get_status' ) ) {
    $status = @opcache_get_status( false );
    echo "get_status()     : ", ( is_array( $status ) ? 'Array' : var_export( $status, true ) ), "\n";
}

$konf = function_exists( 'opcache_get_configuration' ) ? @opcache_get_configuration() : null;
echo "get_configuration: ", ( is_array( $konf ) ? 'Array' : var_export( $konf, true ) ), "\n";
echo "is_script_cached : ", var_export( @opcache_is_script_cached( __FILE__ ), true ), "\n";
echo "sapi             : ", php_sapi_name(), "\n";

Die Fehlerunterdrückung mit @ ist kein Schlamperei-Zeichen, sondern notwendig: Einer der fünf Zustände beantwortet den Aufruf mit einer Warnung, und ohne Unterdrückung landet die im Seitenquelltext.

Der Maßstab: OPcache arbeitet

extension_loaded : true
ini enable       : '1'
ini enable_cli   : '1'
ini restrict_api : ''
hat get_status   : true
get_status()     : Array, opcache_enabled=true
get_configuration: Array, enable=true
is_script_cached : true
sapi             : cli

So sieht der Normalfall aus. Alle drei Auskunftsquellen sind sich einig. Gegen dieses Bild werden die anderen vier gelesen.

Zustand 1: nicht installiert

Fehlt die Erweiterung, ist extension_loaded('Zend OPcache') gleich false, und keine der opcache_*-Funktionen existiert. Jeder Aufruf ohne vorheriges function_exists() beendet die Anfrage mit einem fatalen Fehler.

Diesen Zustand konnte ich auf dem Testserver nicht nachstellen, und das ist selbst ein Befund. Alle fünf dort vorhandenen PHP-Bauten — 8.2 bis 8.5 — haben OPcache fest einkompiliert. Auch php -n -m, also ein Start ohne jede Konfigurationsdatei, listet Zend OPcache weiterhin auf. Wo PHP aus einem gepflegten Paket kommt, ist „nicht installiert“ deutlich seltener als die Ratgeber nahelegen; wahrscheinlicher ist einer der folgenden Zustände.

Zustand 2: geladen, aber abgeschaltet

php -d opcache.enable=0 -d opcache.enable_cli=1 sonde.php

extension_loaded : true
ini enable       : '0'
ini enable_cli   : '1'
hat get_status   : true
get_status()     : false
get_configuration: Array, enable=false
is_script_cached : false

Die Erweiterung ist da, die Funktionen sind da, und opcache_get_status() gibt false zurück. Das entscheidende Merkmal steht eine Zeile tiefer: opcache_get_configuration() antwortet, und in der Antwort steht enable=false. Die Konfiguration sagt selbst, dass sie aus ist.

Das ist neben Zustand 1 der einzige Fall, in dem tatsächlich nichts zwischengespeichert wird und in dem sich etwas ändern lässt. Hier lohnt das Ticket beim Hoster.

Zustand 3: aktiv, aber die Zähler sind gesperrt

Viele Hoster tragen opcache_get_status in disable_functions ein. Der Grund ist nachvollziehbar: Die Funktion verrät unter anderem die Liste aller zwischengespeicherten Dateipfade, und auf einem geteilten Server geht das niemanden etwas an.

php -d opcache.enable_cli=1 -d disable_functions=opcache_get_status sonde.php

extension_loaded : true
ini enable       : '1'
hat get_status   : false
get_status()     : Funktion nicht vorhanden
get_configuration: Array, enable=true
is_script_cached : true

Hier trennt sich die Spreu. Ein Werkzeug, das nur opcache_get_status() kennt, findet die Funktion nicht und meldet OPcache als nicht verfügbar. Zwei Zeilen weiter unten steht aber, dass die Konfiguration ihn als eingeschaltet führt — und die letzte Zeile beweist, dass er tatsächlich arbeitet: Die gerade ausgeführte Datei liegt im Cache.

Dieser Zustand ist keine Theorie. Der Server, auf dem turbopress.de läuft, ist selbst dieser Fall. Gemessen im Web-Kontext, also unter dem SAPI, unter dem auch die Besucher bedient werden:

sapi                 litespeed
extension_loaded     true
ini_enable           1
ini_restrict_api
has_get_status       false
has_get_config       true
config_enable        true
wp_settings_cached   true

opcache_get_status() existiert nicht, und trotzdem liegt wp-settings.php nachweislich im Cache. Jedes Werkzeug, das hier „OPcache ist aus“ meldet, sagt etwas Falsches über eine Installation, an der nichts zu reparieren ist.

Zustand 4: aktiv, aber die API ist auf einen Pfad beschränkt

opcache.restrict_api erlaubt die API nur Skripten unterhalb eines bestimmten Verzeichnisses. Liegt dein Code woanders — und das tut er, wenn der Hoster den Pfad auf sein eigenes Kontrollpanel gesetzt hat —, sieht das so aus:

php -d opcache.enable_cli=1 -d opcache.restrict_api=/ein/anderer/pfad sonde.php

extension_loaded : true
ini enable       : '1'
ini restrict_api : '/ein/anderer/pfad'
hat get_status   : true
get_status()     : Warnung — Zend OPcache API is restricted
                   by "restrict_api" configuration directive
get_configuration: false
is_script_cached : false

Das ist der unangenehmste Zustand, und er unterscheidet sich in einem wichtigen Punkt von Zustand 3: Die Sperre trifft die gesamte API. Ohne Fehlerunterdrückung geben sowohl opcache_get_configuration() als auch opcache_is_script_cached() dieselbe Warnung aus und liefern false.

Die verbreitete Empfehlung, im Zweifel eben opcache_get_configuration() zu nehmen, weil die Funktion die Sperren überlebe, stimmt also nur zur Hälfte. Sie überlebt disable_functions auf eine andere Funktion. Sie überlebt restrict_api nicht.

Das Erkennungsmerkmal ist deshalb die Kombination: Die Funktionen existieren alle, ini_get('opcache.restrict_api') ist nicht leer, und trotzdem antwortet keine von ihnen. In diesem Fall ist von innen nicht feststellbar, ob OPcache arbeitet. Die ehrliche Anzeige lautet dann „unbekannt“, nicht „aus“.

Zustand 5: die Kommandozeile

php sonde.php

extension_loaded : true
ini enable       : '1'
ini enable_cli   : '0'
hat get_status   : true
get_status()     : false
get_configuration: Array, enable=true
is_script_cached : false
sapi             : cli

Standardmäßig ist opcache.enable_cli auf 0. Für die Kommandozeile ist das richtig: Jeder Aufruf ist ein eigener Prozess, ein geteilter Speicher zwischen ihnen existiert nicht, ein Cache brächte nichts.

Praktisch heißt das: Jede Messung über WP-CLI ergibt „OPcache aus“, unabhängig davon, was der Webserver tut. Wer den Zustand einer Website erheben will, muss im Web-Kontext messen. Das Unterscheidungsmerkmal ist php_sapi_name(); steht dort cli, ist das Ergebnis für die Website ohne Aussage.

Die Zustände nebeneinander

ZustandFunktion vorhandenget_configurationis_script_cachedWebsite betroffen
aktivjaArray, enable=truetruenein
nicht installiertneinnicht vorhandennicht vorhandenja
abgeschaltetjaArray, enable=falsefalseja
Funktion gesperrtneinArray, enable=truetruenein
API beschränktjafalsefalseunbekannt
KommandozeilejaArray, enable=truefalsenur die Messung
Die fünf OPcache-Zustände und woran sie sich unterscheiden lassen.

Die Spalte ganz rechts ist die, auf die es ankommt. Zwei Zeilen bedeuten, dass die Website tatsächlich langsamer läuft als nötig. Zwei bedeuten, dass alles in Ordnung ist und nur die Auskunft fehlt. Eine bedeutet, dass die Messung am falschen Ort stattfand.

Wo die Einschränkung konfiguriert ist

Wenn du in Zustand 3 oder 4 landest, lohnt der Blick, wo das eingetragen wurde — schon deshalb, weil ein Ticket mit der genauen Datei schneller beantwortet wird als eines mit „OPcache geht nicht“.

php -i | grep -E "^Loaded Configuration File|^Scan this dir"

PHP liest zuerst eine Hauptdatei und danach jede .ini aus einem Verzeichnis, das oft php.d heißt. Panel-Systeme legen darüber hinaus je Domain eine eigene Datei an, und genau dort stand auf dem hier gemessenen Server die Zeile, die Zustand 3 auslöst:

disable_functions = "opcache_get_status"

Eine einzige Zeile, gesetzt für diese eine Domain, und jedes Werkzeug, das die Zähler ausliest, meldet ab da einen Fehler, den es nicht gibt.

Ein Hinweis zum Argument dahinter: opcache_get_status() nimmt einen Parameter, der bestimmt, ob die Liste aller zwischengespeicherten Skripte mitkommt. Mit false liefert die Funktion nur Zähler — Trefferquote, belegter Speicher, Anzahl der Neustarts — und keine Pfade. Wer beim Hoster nachfragt, hat mit diesem Detail bessere Aussichten als mit der pauschalen Bitte, die Sperre aufzuheben.

Selbst nachsehen

Die Sonde von oben gehört in den Web-Kontext, nicht auf die Kommandozeile. Der kürzeste Weg dorthin ist eine Datei unter wp-content/mu-plugins/, die nur auf einen Parameter reagiert und danach wieder gelöscht wird:

<?php
add_action( 'shutdown', function () {
    if ( ! isset( $_GET['opc'] ) || ! current_user_can( 'manage_options' ) ) {
        return;
    }

    printf(
        "<!-- sapi=%s geladen=%s status=%s konfig=%s gecacht=%s -->",
        php_sapi_name(),
        var_export( extension_loaded( 'Zend OPcache' ), true ),
        var_export( function_exists( 'opcache_get_status' ), true ),
        var_export( is_array( @opcache_get_configuration() ), true ),
        var_export( @opcache_is_script_cached( ABSPATH . 'wp-settings.php' ), true )
    );
}, 99999 );

Der Aufruf erfolgt als angemeldeter Administrator mit angehängtem ?opc=1, und weil ein Seiten-Cache die Anfrage sonst beantwortet, gehört ein zufälliger zweiter Parameter dazu. Das Ergebnis steht als Kommentar im Quelltext.

Gelesen wird es in dieser Reihenfolge: Steht bei sapi etwas anderes als cli, ist die Messung überhaupt gültig. Ist geladen falsch, fehlt die Erweiterung. Ist gecacht wahr, arbeitet OPcache — egal, was die beiden Zeilen davor sagen. Ist gecacht falsch und konfig ebenfalls, dann sieh in ini_get('opcache.restrict_api') nach, bevor du irgendetwas meldest.

Turbopress Database Diagnostics unterscheidet diese fünf Zustände und nimmt die drei, die vom Hosting kommen, aus der Bewertung heraus, statt sie als Mangel der Installation zu zählen.

Wo OPcache in der Rangfolge der Dinge steht, die eine Antwortzeit bestimmen, steht hier: TTFB verbessern. Weitere Messungen aus derselben Reihe sammeln sich unter Wissen.

Welcher PHP-Handler OPcache bereitstellt und wie er konfiguriert ist, legt das Hosting fest. Bei turbopress läuft PHP über LSPHP; was sonst zum Stack gehört, steht im turbopress Tech-Stack.

turbopress

Der turbopress WordPress Tech-Stack

WordPress ist oft nicht sehr performant, deswegen haben wir einen Tech-Stack im Einsatz, der dieses Problem adressiert und behebt, ohne dass du Aufwand hast:

Moderne Hardware

Server mit NVMe SSDs im RAID, 10 GBit/s Anbindung und schnellen AMD EPYC Prozessoren bilden die Basis für maximale Performance.

Optimierte Software

LiteSpeed Enterprise Webserver mit LSCWP und LSCache sowie Valkey Object-Cache machen deinem WordPress Beine.

Next-Gen Protokolle

HTTP/3 über QUIC & TLS 1.3: schnellere Verbindungen, weniger Latenz, stabil mobil, sicherer.

Isolierte Umgebung

Dein Hosting verfügt über eigene Ressourcen und wird nicht durch „Noisy Neighbors“ beeinträchtigt. Schnell und sicher.