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 vote has been reset, and the status is back to Under Discussion. It needs a two-thirds majority to pass.