PHP 8.0: New preg_last_error_msg function

Version8.0
TypeNew Feature

Some of the legacy PHP functionality does not throw exceptions on errors, and it is up to the caller to check if an operation was successful or not.

When you run a regular expression using PHP's preg_ functions, these functions do not throw an exception if something went wrong. It is up to the caller to retrieve any error messages using preg_last_error function, which returns an error code if there were any errors.

PHP's core json_encode() and json_decode() functions follow a similar pattern, and unless the exception behavior is explicitly requested (PHP 7.3+), you have to call json_last_error function to retrieve any errors occurred during the last operation. However, JSON functionality comes with a json_last_error_msg() function to retrieve the human-friendly error message of the JSON encode/decode error.

PREG functionality did not come with a function to retrieve the human-friendly error message. PHP 8.0 brings one!

The new preg_last_error_msg() returns a human-friendly error message, or "No error" (as string) if there were no errors.

preg_match('/(?:\D+|<\d+>)*[!?]/', 'foobar foobar foobar');
var_dump(preg_last_error()); // 2

With the new preg_last_error_msg() function, you can directly get the error message:

preg_match('/(?:\D+|<\d+>)*[!?]/', 'foobar foobar foobar');
var_dump(preg_last_error()); // 2
var_dump(preg_last_error_msg()); // Backtrack limit was exhausted

Polyfill

The new preg_last_error_msg() function simply returns a human-friendly text error message instead of the error code. This can be polyfilled with a hardcoded list of error codes mapped to error messages:

if (!function_exists('preg_last_error_msg')) {
    /**
    * Returns the error message of the last PCRE regex execution.
    * @return string
    */
    function preg_last_error_msg(): string {
        switch (preg_last_error()) {
            case PREG_NO_ERROR:
                return 'No error';
            case PREG_INTERNAL_ERROR:
                return 'Internal error';
            case PREG_BACKTRACK_LIMIT_ERROR:
                return 'Backtrack limit exhausted';
            case PREG_RECURSION_LIMIT_ERROR:
                return 'Recursion limit exhausted';
            case PREG_BAD_UTF8_ERROR:
                return 'Malformed UTF-8 characters, possibly incorrectly encoded';
            case PREG_BAD_UTF8_OFFSET_ERROR:
                return 'The offset did not correspond to the beginning of a valid UTF-8 code point';
            case PREG_JIT_STACKLIMIT_ERROR:
                return 'JIT stack limit exhausted';

            default:
                return 'Unknown error';
        }
    }
}

Backwards compatibility impact

preg_last_error_msg() is a new function, and unless you have declared a function with the same name in global namespace, there should be no BC issues.


Externals.io discussion Implementation