[PHP-DEV][PRE-RFC] PREG_THROW_ON_ERROR flag

Hi all,

I’d like to propose adding a PREG_THROW_ON_ERROR flag to the preg_*() functions, and gauge interest in that.

Json and ext/filter both grew an opt-in way to turn a silent error into an exception…that is JSON_THROW_ON_ERROR and FILTER_THROW_ON_FAILURE.
PCRE is the one left out where a failing call is easy to miss. An execution error for example (e.g. a bad UTF-8) surfaces only if
you call preg_last_error() afterwards, and a malformed pattern emits a warning and returns false.

PREG_THROW_ON_ERROR would do for PCRE what those two do for their functions.
Passing it to any preg_*() call makes a PCRE error throw a Pcre\PcreException that carries the PREG_*_ERROR code and the preg_last_error_msg() text
instead of warning or returning false/null.
And it covers both kinds: a compilation error (e.g. a malformed pattern) and an execution error, so opting in means any PCRE failure becomes a single catchable exception.
Also, preg_replace() and preg_filter() gain an optional $flags parameter to accept it (the only two without one as far as I know).

Concretely, the check you’d write today:

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

…collapses to:

preg_match($pattern, $subject, $m, PREG_THROW_ON_ERROR);

First, I’d like to know whether there’s interest at all and whether anyone sees a reason not to add it.

If there is interest, a couple of design questions I’d want the list’s read on:

  1. Array subjcets. Currently preg_last_error() reflects only the last element processed, but I’d have the flag throw on the first failing element rather than keep last-one-wins…does that seem right?
  2. Whether *_ON_ERROR reads better than *_ON_FAILURE given the existing preg_last_error()/PREG_*_ERROR vocabulary.
    If it seems worth pursuing, I’ll write it up as a proper RFC.

Thanks,
Osama

On Tue, Jul 7, 2026 at 4:17 AM Osama Aldemeery <aldemeery@gmail.com> wrote:

Hi all,

I’d like to propose adding a PREG_THROW_ON_ERROR flag to the preg_*() functions, and gauge interest in that.

Json and ext/filter both grew an opt-in way to turn a silent error into an exception…that is JSON_THROW_ON_ERROR and FILTER_THROW_ON_FAILURE.
PCRE is the one left out where a failing call is easy to miss. An execution error for example (e.g. a bad UTF-8) surfaces only if
you call preg_last_error() afterwards, and a malformed pattern emits a warning and returns false.

PREG_THROW_ON_ERROR would do for PCRE what those two do for their functions.
Passing it to any preg_*() call makes a PCRE error throw a Pcre\PcreException that carries the PREG_*_ERROR code and the preg_last_error_msg() text
instead of warning or returning false/null.
And it covers both kinds: a compilation error (e.g. a malformed pattern) and an execution error, so opting in means any PCRE failure becomes a single catchable exception.
Also, preg_replace() and preg_filter() gain an optional $flags parameter to accept it (the only two without one as far as I know).

Concretely, the check you’d write today:

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

…collapses to:

preg_match($pattern, $subject, $m, PREG_THROW_ON_ERROR);

First, I’d like to know whether there’s interest at all and whether anyone sees a reason not to add it.

If there is interest, a couple of design questions I’d want the list’s read on:

  1. Array subjcets. Currently preg_last_error() reflects only the last element processed, but I’d have the flag throw on the first failing element rather than keep last-one-wins…does that seem right?
  2. Whether *_ON_ERROR reads better than *_ON_FAILURE given the existing preg_last_error()/PREG_*_ERROR vocabulary.
    If it seems worth pursuing, I’ll write it up as a proper RFC.

Thanks,
Osama

Hi all,

I’ve put together a complete implementation across all the preg_*() functions so I can open a PR if it helps the discussion.

For now I’ve got it throwing on the first failing element for arrays, and went with PREG_THROW_ON_ERROR for the flag name, just so I could complete the implementation.
Still eager to hear what people have to say about that though, and to know whether there’s interest/objection before I take it further.

Thanks,
Osama