New error messages in PHP 8.1

With PHP 8.1 around the corner, it is time to take a look at the error messages that are going to become soon part of our life. They are a precious source of information when preparing the migration from PHP 8.0 to 8.1, for the Exakat engine :

Here are the stats of error messages in PHP 8.1.

Total error messages

In PHP 8.1, there are 2575 total error messages in the code. That is a little more than the 2411 errors in PHP 8.0, and a classic evolution : major versions tend to drop the deprecated messages from the previous one, while middle versions tend to accumulate them.

PHP 8.1 is also well below the maximum of 4156 error messages in PHP 5.6.

Distinct error messages

PHP 8.1 has 411 distinct error messages. It is a slight uptick from the 382 of PHP 8.0.

Most common error messages

With an average of 6.27 repetitions of an error messages, some of them are spread more often than others. Here are the most repeated error messages in PHP source :

Error message Count
Only variable references should be yielded by reference 84
internal error 80
arithmetic overflow 60
Undefined variable $%s 42
Undefined array key 30
foreach() argument must be of type array|object 24
Only variable references should be returned by reference 24

It is interesting to see that some of the most commonly happening errors (Undefined variable anyone?) are also the most common in the code.

Type of errors

The type of error is also available in the PHP source, and here is the repartition.

Compile time errors are the most common, followed by the warnings. The source of Fatal error, aka E_ERROR are only third, with a 14% of market share. Deprecated errors represents only 4% of the total.

Error level Count

These counts are by total number of error message (not by distinct message). The total is also lower than the initial count, as some of the error types are sometimes provided as variables or expressions, whose value was not retrieved at analyze time.

In and out error messages

There are 46 new PHP 8.1 error messages. Here are the new ones :

  • %s implements the Serializable interface
  • %s must be registered before %s
  • %s(): ISO interval must contain a start date, “%s
  • %s(): ISO interval must contain an end date or a recurrence count, “%s
  • %s(): ISO interval must contain an interval, “%s
  • %s(): Recurrence count must be greater than 0
  • %s: Uncaught %s
  • %s::%s cannot override final constant %s::%s
  • %s::%s is not a case
  • Access type for interface method %s::%s() must be public
  • Accessing static trait property %s::$%s is deprecated
  • Callables of the form [“%s
  • Called %s() on an invalid iterator
  • Called current() on invalid iterator
  • Calling static trait method %s::%s is deprecated
  • Cannot clone unconstructed IntlDatePatternGenerator
  • Cannot redeclare %s property %s::$%s as %s %s::$%s
  • Case %s of non-backed enum %s must not have a value
  • Case %s::%s does not exist
  • Class %s cannot extend %s %s
  • Class %s cannot extend final class %s
  • Class %s inherits both %s::%s and %s::%s
  • Constant %s::%s is not a case
  • Enum backing type must be int or string
  • Enum case %s::%s is not a backed case
  • FTP\Connection is already closed
  • Failed to parse interval (%s)
  • Failed to parse time string (%s) at position %d (%c): %s
  • Fiber stack allocate failed: VirtualAlloc failed: [0x%08lx] %s
  • Fiber stack allocate failed: mmap failed: %s (%d)
  • Fiber stack protect failed: VirtualProtect failed: [0x%08lx] %s
  • Fiber stack protect failed: mprotect failed: %s (%d)
  • IMAP\Connection is already closed
  • Interface %s cannot extend class %s
  • Invalid opcode name %.*s
  • Multiple readonly modifiers are not allowed
  • Optional parameter $%s declared before required parameter $%s is implicitly treated as a required parameter
  • Private constant %s::%s cannot be final as it is not visible to other classes
  • Readonly property %s::$%s cannot have default value
  • Readonly property %s::$%s must have type
  • Result is identity element
  • SQLSTATE[%s] [%ld] %s
  • Static property %s::$%s cannot be readonly
  • Undefined %svariable $%s
  • Unhandled match case %s
  • Unknown or bad format (%s)

There are 17 PHP 8.0 removed error messages. Some were updated, and also appear above. Here are the removed ones :

  • Access type for interface method %s::%s() must be omitted
  • Cannot access non-public property %s::$%s
  • Cannot call non-static method %s::%s() without object
  • Cannot inherit previously-inherited or override constant %s from interface %s
  • Class %s cannot extend from interface %s
  • Class %s cannot extend from trait %s
  • Class %s may not inherit from final class (%s)
  • During inheritance of %s with variance dependencies: Uncaught %s
  • Failed to load class %s used by typed property %s::$%s during preloading
  • Interface %s may not inherit from class (%s)
  • Invalid callback %s
  • Required parameter $%s follows optional parameter $%s
  • Resource ID#%d used as offset
  • SQLSTATE[%s] [%d] %s
  • Trying to invoke %s method %s::%s() from scope %s
  • Unable to connect to UNIX domain socket at %s defined by phpdbg.path ini setting. Reason: %s
  • Unhandled match value of type %s

Time to try PHP 8.1

Now that you know all there is about PHP error messages, you can take a dive with it, and test drive your own code with the versions.

There is a long list of those pesky error messages in Exakat’s documentation, to help you track then before they hit your production code.

Consider a thank you note to the Release Masters of this version : Patrick Allaert, Ben Ramsey and Joe Watkins.