W3docs

preg_last_error()

Erfahren Sie, wie preg_last_error() in PHP den Fehlercode des letzten PCRE-Aufrufs liefert, mit Fehlerkonstanten und Beispielen.

Einführung

Reguläre Ausdrücke sind ein leistungsfähiges Werkzeug zum Verarbeiten und Durchsuchen von Zeichenketten in PHP. Gelegentlich schlagen Regex-Operationen aufgrund ungültiger Muster oder Engine-Limits fehl. Die Funktion preg_last_error() hilft dabei, diese Fehler zu identifizieren, indem sie den Fehlercode des letzten PCRE-Funktionsaufrufs zurückgibt.

Syntax

preg_last_error(): int

Die Funktion nimmt keine Argumente entgegen. Sie gibt eine ganzzahlige Konstante zurück, die beschreibt, was beim letzten PCRE-Funktionsaufruf schiefgelaufen ist — z. B. bei preg_match(), preg_match_all(), preg_replace() oder preg_split(). Wenn der letzte Aufruf erfolgreich war, gibt sie PREG_NO_ERROR (0) zurück.

Warum Sie sie benötigen

PCRE-Funktionen sind ungewöhnlich: Wenn sie fehlschlagen, werfen sie keine Exception. Stattdessen gibt preg_match() false zurück (nicht 0 — das bedeutet „kein Treffer"), und preg_replace() gibt null zurück. Diese Rückgabewerte sagen Ihnen, dass etwas schiefgelaufen ist, aber nicht warum. preg_last_error() schließt diese Lücke, indem es den zugrunde liegenden Grund meldet.

Deshalb müssen Sie mit === statt einem lockeren == vergleichen: 0 (kein Treffer) und false (Fehler) wirken beide „falsy", bedeuten aber sehr unterschiedliche Dinge.

Fehlerkonstanten

preg_last_error() gibt eine der folgenden ganzzahligen Konstanten zurück. Die numerischen Werte sind zur Referenz angegeben, aber Sie sollten immer gegen die benannte Konstante vergleichen.

KonstanteWertBedeutung
PREG_NO_ERROR0Kein Fehler — die letzte Operation war erfolgreich.
PREG_INTERNAL_ERROR1Ein interner PCRE-Fehler (oft ein fehlerhaftes Muster).
PREG_BACKTRACK_LIMIT_ERROR2Das Muster hat das pcre.backtrack_limit überschritten.
PREG_RECURSION_LIMIT_ERROR3Das Muster hat das pcre.recursion_limit überschritten.
PREG_BAD_UTF8_ERROR4Das Subjekt ist kein gültiges UTF-8 (mit dem Modifikator u).
PREG_BAD_UTF8_OFFSET_ERROR5Der Offset entspricht nicht dem Beginn eines gültigen UTF-8-Codepunkts.
PREG_JIT_STACKLIMIT_ERROR6Das Muster hat das JIT-Stack-Limit erschöpft.

Seit PHP 8.0 gibt preg_last_error_msg() dieselben Informationen als lesbaren String zurück, was für die Protokollierung sehr praktisch ist.

Einen Fehler auslösen und auslesen

Ein häufiger Fehler in der Praxis ist katastrophales Backtracking, bei dem ein schlecht geschriebenes Muster die Engine zwingt, eine enorme Anzahl von Pfaden auszuprobieren, und das Backtrack-Limit überschreitet. Das folgende Beispiel senkt pcre.backtrack_limit, damit der Fehler reproduzierbar ist, und untersucht dann das Ergebnis.

<?php

// Lower the limit so the failure is easy to reproduce.
ini_set('pcre.backtrack_limit', '100');

$pattern = '/(\w+)*$/';            // nested quantifier — backtracks heavily
$string  = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!';

$result = preg_match($pattern, $string, $matches);

if ($result === false) {
    echo 'preg_match() failed!' . PHP_EOL;
    echo 'Error code: ' . preg_last_error() . PHP_EOL;
    echo 'Error message: ' . preg_last_error_msg() . PHP_EOL;

    if (preg_last_error() === PREG_BACKTRACK_LIMIT_ERROR) {
        echo 'The pattern was too expensive to evaluate.' . PHP_EOL;
    }
} elseif ($result === 1) {
    echo 'Match found.' . PHP_EOL;
} else {
    echo 'No match.' . PHP_EOL;
}

Ausgabe:

preg_match() failed!
Error code: 2
Error message: Backtrack limit exhausted
The pattern was too expensive to evaluate.

Der Fehlercode 2 entspricht PREG_BACKTRACK_LIMIT_ERROR. Entscheidend ist, dass die Prüfung if ($result === false) uns mitteilt, dass ein echter Fehler aufgetreten ist — ein 0 würde hier lediglich bedeuten, dass das Muster nicht übereinstimmt.

Ungültige UTF-8-Eingaben erkennen

Wenn Sie den Modifikator u (Unicode) auf einen String anwenden, der kein gültiges UTF-8 ist, bricht PCRE ab und setzt PREG_BAD_UTF8_ERROR:

<?php

$result = preg_match('/./u', "\x80");   // \x80 is not a valid UTF-8 sequence

if ($result === false && preg_last_error() === PREG_BAD_UTF8_ERROR) {
    echo 'Invalid UTF-8 input: ' . preg_last_error_msg();
}
// Invalid UTF-8 input: Malformed UTF-8 characters, possibly incorrectly encoded

Dies ist eine häufige Quelle stiller Fehler bei der Verarbeitung von Benutzereingaben, daher ist es eine gute Praxis, dagegen abzusichern.

Häufige Stolpersteine

  • Sofort prüfen. preg_last_error() spiegelt nur den letzten PCRE-Aufruf wider. Jeder spätere Regex-Aufruf überschreibt ihn, also lesen Sie ihn unmittelbar nach der betreffenden Operation aus.
  • false vs. 0. Verwenden Sie immer ===. preg_match() gibt 0 für „kein Treffer" und false für einen Fehler zurück — diese sind nicht austauschbar.
  • Fehler bei preg_replace(). Wenn preg_replace() null zurückgibt, lohnt es sich ebenfalls, preg_last_error() aufzurufen, um den Grund zu erfahren.

Fazit

preg_last_error() wandelt ein undurchsichtiges false-Ergebnis in einen verwertbaren Grund um und ist damit unverzichtbar für das Debuggen regulärer Ausdrücke in PHP. Durch den Vergleich von Rückgabewerten mit === und die Auswertung des Fehlercodes (oder preg_last_error_msg()) können Sie Engine-Fehler sauber von einfachen Nicht-Treffern trennen. Für die Funktionen, deren Fehler es meldet, siehe preg_match(), preg_replace() und preg_split().

Übungen

Übung
Was macht die Funktion 'preg_last_error' in PHP?
Was macht die Funktion 'preg_last_error' in PHP?
Was this page helpful?