Start · Sprachen · PHP · Referenz · preg_last_error

preg_last_error

Funktion

Gibt den Fehlercode der zuletzt ausgeführten PCRE-Regex-Operation zurück, um Fehler wie <code>PREG_BACKTRACK_LIMIT_ERROR</code> oder <code>PREG_RECURSION_LIMIT_ERROR</code> zu erkennen.

seit PHP 5.2.0 Kategorie: regex

Signatur

preg_last_error(): int

Beschreibung

preg_last_error() liefert einen ganzzahligen Fehlercode, der den Status der zuletzt durchgeführten PCRE-Regulärausdrucks-Operation beschreibt. Da PCRE-Funktionen wie preg_match() oder preg_replace() bei internen Fehlern häufig false oder null zurückgeben, ohne den genauen Grund zu nennen, ermöglicht diese Funktion eine präzise Fehlerdiagnose.

Die zurückgegebenen Fehlercodes entsprechen vordefinierten Konstanten: PREG_NO_ERROR (0) bedeutet keinen Fehler, PREG_INTERNAL_ERROR (1) zeigt einen internen PCRE-Fehler an, PREG_BACKTRACK_LIMIT_ERROR (2) und PREG_RECURSION_LIMIT_ERROR (3) weisen auf überschrittene Limits aus der php.ini (pcre.backtrack_limit bzw. pcre.recursion_limit) hin. PREG_BAD_UTF8_ERROR (4) und PREG_BAD_UTF8_OFFSET_ERROR (5) signalisieren Probleme mit ungültigem UTF-8-Input.

Ab PHP 8.0 empfiehlt sich alternativ preg_last_error_msg(), die eine lesbare Fehlermeldung als String liefert. In älteren PHP-Versionen ist preg_last_error() jedoch die einzige Möglichkeit, detaillierte PCRE-Fehlerinformationen abzurufen.

Typischer Einsatz: nach jedem kritischen preg_match()- oder preg_replace()-Aufruf prüfen, ob das Ergebnis false ist, und dann preg_last_error() auswerten, um den Fehlergrund zu ermitteln und gegebenenfalls Limits anzupassen oder den Input zu validieren.

Rückgabewert

Typ
int
Beschreibung
Gibt einen der PCRE-Fehlercodes zurück: PREG_NO_ERROR (0) bei Erfolg, PREG_INTERNAL_ERROR (1), PREG_BACKTRACK_LIMIT_ERROR (2), PREG_RECURSION_LIMIT_ERROR (3), PREG_BAD_UTF8_ERROR (4), PREG_BAD_UTF8_OFFSET_ERROR (5) oder PREG_JIT_STACKLIMIT_ERROR (6, ab PHP 7.0).

Beispiele

Backtrack-Limit-Fehler erkennen

<?php
// Ein Muster, das exzessives Backtracking erzeugt
$pattern = '/(?:a+)+$/';
$subject = str_repeat('a', 50) . 'b';

$result = preg_match($pattern, $subject);

if ($result === false) {
    $errorCode = preg_last_error();
    switch ($errorCode) {
        case PREG_BACKTRACK_LIMIT_ERROR:
            echo 'Fehler: Backtrack-Limit überschritten (pcre.backtrack_limit).' . PHP_EOL;
            break;
        case PREG_RECURSION_LIMIT_ERROR:
            echo 'Fehler: Rekursions-Limit überschritten (pcre.recursion_limit).' . PHP_EOL;
            break;
        case PREG_INTERNAL_ERROR:
            echo 'Fehler: Interner PCRE-Fehler.' . PHP_EOL;
            break;
        default:
            echo 'Unbekannter PCRE-Fehler: ' . $errorCode . PHP_EOL;
    }
} else {
    echo 'Treffer gefunden: ' . ($result ? 'Ja' : 'Nein') . PHP_EOL;
}
Fehler: Backtrack-Limit überschritten (pcre.backtrack_limit).

Hilfsfunktion zur lesbaren Fehlerausgabe

<?php
function pcreErrorName(int $code): string {
    $errors = [
        PREG_NO_ERROR              => 'PREG_NO_ERROR',
        PREG_INTERNAL_ERROR        => 'PREG_INTERNAL_ERROR',
        PREG_BACKTRACK_LIMIT_ERROR => 'PREG_BACKTRACK_LIMIT_ERROR',
        PREG_RECURSION_LIMIT_ERROR => 'PREG_RECURSION_LIMIT_ERROR',
        PREG_BAD_UTF8_ERROR        => 'PREG_BAD_UTF8_ERROR',
        PREG_BAD_UTF8_OFFSET_ERROR => 'PREG_BAD_UTF8_OFFSET_ERROR',
    ];
    return $errors[$code] ?? 'UNBEKANNT (' . $code . ')';
}

// UTF-8-Fehler provozieren
$invalidUtf8 = "\xc3\x28"; // ungültige UTF-8-Sequenz
$result = preg_match('/./u', $invalidUtf8);

if ($result === false) {
    echo 'PCRE-Fehler: ' . pcreErrorName(preg_last_error()) . PHP_EOL;
} else {
    echo 'Kein Fehler, Ergebnis: ' . $result . PHP_EOL;
}
PCRE-Fehler: PREG_BAD_UTF8_ERROR

// Wichtig · Fallstricke

PHP 8.0+: Seit PHP 8.0 steht preg_last_error_msg() zur Verfügung, die direkt eine lesbare Fehlermeldung als String zurückgibt und preg_last_error() in den meisten Fällen ersetzt.

Limits anpassen: Bei PREG_BACKTRACK_LIMIT_ERROR kann ini_set('pcre.backtrack_limit', 10000000) helfen, jedoch ist es besser, das Regex-Muster zu optimieren (z. B. durch atomare Gruppen oder besitzgreifende Quantoren), um katastrophales Backtracking zu vermeiden.

Fehlercode bleibt gespeichert: Der Fehlercode wird pro Request gesetzt und bleibt bis zum nächsten PCRE-Aufruf erhalten. Immer direkt nach dem verdächtigen Aufruf prüfen, nicht erst später im Code.