W3docs

preg_last_error()

Apprenez comment preg_last_error() de PHP retourne le code d'erreur du dernier appel PCRE, avec les constantes d'erreur et des exemples.

Introduction

Les expressions régulières sont un outil puissant pour manipuler et rechercher des chaînes de caractères en PHP. Parfois, les opérations regex échouent en raison de motifs invalides ou de limites du moteur. La fonction preg_last_error() aide à identifier ces échecs en renvoyant le code d'erreur du dernier appel à une fonction PCRE.

Syntaxe

preg_last_error(): int

La fonction ne prend aucun argument. Elle retourne une constante entière décrivant ce qui s'est mal passé lors du dernier appel à une fonction PCRE — comme preg_match(), preg_match_all(), preg_replace() ou preg_split(). Si le dernier appel a réussi, elle retourne PREG_NO_ERROR (0).

Pourquoi en avez-vous besoin

Les fonctions PCRE sont particulières : lorsqu'elles échouent, elles ne lèvent pas d'exception. À la place, preg_match() retourne false (et non 0 — ce qui signifie « aucune correspondance »), et preg_replace() retourne null. Ces valeurs de retour vous indiquent qu'une chose a échoué, mais pas pourquoi. preg_last_error() comble cet écart en rapportant la raison sous-jacente.

C'est pourquoi vous devez comparer avec === plutôt qu'un == souple : 0 (aucune correspondance) et false (erreur) semblent tous deux « falsy », mais ils ont des significations très différentes.

Constantes d'erreur

preg_last_error() retourne l'une de ces constantes entières. Les valeurs numériques sont indiquées à titre de référence, mais vous devez toujours comparer avec la constante nommée.

ConstanteValeurSignification
PREG_NO_ERROR0Aucune erreur — la dernière opération a réussi.
PREG_INTERNAL_ERROR1Une erreur interne PCRE (souvent un motif malformé).
PREG_BACKTRACK_LIMIT_ERROR2Le motif a atteint la limite pcre.backtrack_limit.
PREG_RECURSION_LIMIT_ERROR3Le motif a atteint la limite pcre.recursion_limit.
PREG_BAD_UTF8_ERROR4Le sujet n'est pas un UTF-8 valide (avec le modificateur u).
PREG_BAD_UTF8_OFFSET_ERROR5Le décalage ne correspond pas au début d'un point de code UTF-8 valide.
PREG_JIT_STACKLIMIT_ERROR6Le motif a épuisé la limite de pile JIT.

Depuis PHP 8.0, preg_last_error_msg() retourne les mêmes informations sous forme de chaîne lisible par un humain, ce qui est pratique pour la journalisation.

Déclencher et lire une erreur

Un échec courant en situation réelle est le retour arrière catastrophique (catastrophic backtracking), où un motif mal écrit force le moteur à essayer un nombre énorme de chemins et dépasse la limite de retour arrière. L'exemple ci-dessous abaisse pcre.backtrack_limit pour que l'échec soit reproductible, puis examine le résultat.

<?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;
}

Résultat :

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

Le code d'erreur 2 correspond à PREG_BACKTRACK_LIMIT_ERROR. Il est crucial que la vérification if ($result === false) soit ce qui nous indique qu'une vraie erreur s'est produite — un 0 ici signifierait simplement que le motif n'a pas trouvé de correspondance.

Détecter une entrée UTF-8 invalide

Lorsque vous utilisez le modificateur u (unicode) sur une chaîne qui n'est pas un UTF-8 valide, PCRE abandonne et définit 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

C'est une source fréquente de bugs silencieux lors du traitement de données soumises par des utilisateurs, donc s'en prémunir est une bonne pratique.

Pièges courants

  • Vérifiez immédiatement. preg_last_error() ne reflète que le dernier appel PCRE. Tout appel regex ultérieur l'écrase, alors lisez-le juste après l'opération qui vous intéresse.
  • false vs 0. Utilisez toujours ===. preg_match() retourne 0 pour « aucune correspondance » et false pour une erreur — ils ne sont pas interchangeables.
  • Échecs de preg_replace(). Lorsque preg_replace() retourne null, il vaut également la peine d'appeler preg_last_error() pour savoir pourquoi.

Conclusion

preg_last_error() transforme un retour false opaque en une raison exploitable, ce qui en fait un outil essentiel pour déboguer les expressions régulières en PHP. En comparant les valeurs de retour avec === et en inspectant le code d'erreur (ou preg_last_error_msg()), vous pouvez distinguer proprement les échecs du moteur des simples non-correspondances. Pour les fonctions dont elle rapporte les échecs, consultez preg_match(), preg_replace() et preg_split().

Pratique

Pratique
Que fait la fonction 'preg_last_error' en PHP ?
Que fait la fonction 'preg_last_error' en PHP ?
Was this page helpful?