When a regular expression fails in PHP, it's easy not to notice. A bad pattern or invalid UTF-8 gives you false or null, and a quick check can't tell that apart from "no match." This RFC from Osama Aldemeery adds a PREG_THROW_ON_ERROR flag. Pass it to a preg_*() function, and an error throws a \PregException you can catch.

PHP has done this twice before. json_decode() got JSON_THROW_ON_ERROR in PHP 7.3, and the filter extension got FILTER_THROW_ON_FAILURE in PHP 8.5.

Show me

Today you have to check the result yourself:

if (preg_match($pattern, $subject, $matches) === false) {
    throw new RuntimeException(preg_last_error_msg());
}

With the flag, you catch an exception instead:

try {
    $count = preg_match_all($pattern, $subject, $matches, PREG_THROW_ON_ERROR);
} catch (\PregException $e) {
    // same code and message as preg_last_error()
    // and preg_last_error_msg()
}

How it works

The flag works with all eight preg_*() functions that do matching:

  • preg_match() and preg_match_all()
  • preg_replace() and preg_filter()
  • preg_replace_callback() and preg_replace_callback_array()
  • preg_split() and preg_grep()

preg_replace() and preg_filter() had no $flags parameter, so each gets a new one at the end.

PregException extends \Exception. Its code matches preg_last_error(), and its message matches preg_last_error_msg(). The flag adds no new error conditions. It only turns the error you'd already get into an exception.

A few details:

  • Bad patterns still emit the detailed "Compilation failed" warning. The exception message only says "Internal error," the same as preg_last_error_msg().
  • Arrays follow the same rules as today. If a later item succeeds and clears the error, nothing is thrown.
  • Callbacks keep their own exceptions. If your callback throws, that exception takes priority.
  • $matches and $count aren't reliable after an exception, so only use them when the call succeeds.

What it means for existing code

Nothing breaks. The flag is opt-in, so calls without it behave exactly as before. IDEs and static analyzers will need to add the new constant, the new class and the new $flags parameter.

Where it stands

The RFC is under discussion and targets PHP 8.7. A vote opened on September 4, 2026, and in that thread Tim Düsterhus raised concerns about how the flag handles errors and exceptions from callbacks. The page now shows a restarted poll with no votes, and the status is back to Under Discussion. It needs a two-thirds majority to pass.