---
title: "New PHP error messages in PHP 8.2"
url: https://www.exakat.io/new-php-errors-messages-in-php-8-2/
date: 2022-06-27
modified: 2023-12-27
author: "dams"
description: "New PHP errors messages in PHP 8.2 The upcoming PHP 8.2 is bringing some new errors messages, either from new features, or from extra checks on the source code. Let's..."
categories:
  - "Code auditing"
word_count: 1229
---

# New PHP error messages in PHP 8.2

# New PHP errors messages in PHP 8.2

The upcoming PHP 8.2 is bringing some new errors messages, either from new features, or from extra checks on the source code. Let's review their numbers, and some of the extra checking that will help us.

## Evolution of error message counts

With distinct 751 error messages, PHP 8.2 is only ranking number 4, quite far behing PHP 7.4 with its 824 error messages.

[![](https://www.exakat.io/wp-content/uploads/2022/06/PHP-8.2-error-message-counts-1024x578.png)](https://www.exakat.io/wp-content/uploads/2022/06/PHP-8.2-error-message-counts.png)

 

Usually, the distinct number of error messages grow within a PHP major version, as deprecations are accumulated until the next breaking change version : at that point, they are removed and the whole number drops significantly. We'll see what happens with PHP 9.0.

## New error messages

PHP 8.2 adds 22 new error messages, and removes 13 of them, for a net increase of 9.

Quick disclaimer : the error messages are read from PHP code source, which is in C. The `%s` is the place holder for strings, just like with sprintf() in PHP. They usually carry a name, which is dynamically filled by PHP.

Here are the new PHP errors.

## Callables of the form ["Foo", "parent::bar"] are deprecated

Several syntaxes used to defined callables are deprecated in PHP 8.2. This is one of them, and there are several variations, with `parent`, `static`, `self` or the class name.

[RFC](https://wiki.php.net/rfc/deprecate_partially_supported_callables)

### Cannot apply #[AllowDynamicProperties] to interface

### Cannot apply #[AllowDynamicProperties] to readonly class %s

### Cannot apply #[AllowDynamicProperties] to trait

The deprecation of the (wanted or not) dynamic properties is going to be a big hit with PHP 8.2 : ambiguity intended.

The `AllowDynamicProperties` attribute is introduced to deflect that problem. Applied to classes, it allows the dynamic properties that are now, by default, forbidden.

Yet, this is a class-only attribute, so it is not possible to put it on trait (for example), and spread it across the code source. Class only.

Also, linted before execution.

[RFC](https://wiki.php.net/rfc/deprecate_dynamic_properties)

### Creation of dynamic property x::$y is deprecated

Deprecation message, for execution time.

## Type contains both true and false, bool should be used instead

PHP 8.2 introduces the type `true`, as a complement to the type `false`. It is now possible to type `true` a method that only returns `true` or a property that only holds `true` (and nothing else).

This error message detects that `true` and `false` are used at the same time, and they should actually be merged in `bool`.

In PHP 8.1 and older, `true` is confused with a class, and gets its own error message : `Cannot use 'true' as class name as it is reserved`.

[RFC](https://wiki.php.net/rfc/null-false-standalone-types)

## Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead

## Using ${var} in strings is deprecated, use {$var} instead

Two error messages dedicated to the deprecation of the `${}` operator. It used to be a very clever way to make variable variables, and it was also mostly unused.

This should be very rare, as the number of occurrences are below 20 over 2000 PHP projects.

[RFC](https://wiki.php.net/rfc/deprecate_dollar_brace_string_interpolation)

## iterable type is now a compile time alias for array|Traversable

As detailled in the UPGRADING document, iterable is now a built-in type, and it is replaced on the fly by `array` and `Traversable`. This changes the old error messages, but not the behavior of PHP.

Also, iterable unioned with other types will simply extends the list of types availables.

As for intersectional types, which would use `iterable` to not be pure types, it is already monitored by PHP with `Type iterable cannot be part of an intersection type`.

## null cannot be marked as nullable

Well, what else to say ? Someone has to try it : we did. It works as expected.

### %s class %s cannot extend %s class %s

Usually the `%s` is a placeholder for a name. And, in this very case, it is for a property : readonly classes can't be extended by non-readonly classes.

Readonly classes are new in PHP 8.2 : they are an extension of the readonly properties, available in PHP 8.1. The option covers a whole class, and each of its property are now readonly, without extra specification, like for final.

This is detected at compilation time, when the classes are in the right order (like here). When they are in the reverse order, or split across multiple files, this appears at execution time.

[RFC](https://wiki.php.net/rfc/readonly_classes)

## %s::__toString() implemented without string return type

This error looks like a twin of `Bar::__toString(): Return type must be string when declared`. Yet, we could not reproduce it. Anyone with that 'luck' ?

## Updated error messages

The updated error messages are usually rewriting of previous ones. We would say refactored.

### %s %s cannot implement previously implemented interface %s

This one is easy to spot, including when `use` command is at work. The error message appears after `Interface "i" not found` (here), and only at execution time.

Also, this is not checked across classes, within a class family. For this, there is [Already Parent Interface](https://exakat.readthedocs.io/en/latest/Reference/Rules.html#already-parents-interface).

### %s %s inherits both %s::%s and %s::%s

This error messages happens when a constant is defined both in an interface and in a class. This is a conflict, even when the value of the constant is the same. Unlike trait, there are no way arbitrage this conflict, and it leads to a fatal error.

## %s %s must implement interface %s as part of either %s or %s

Traversable cannot be implemented directly, but only through Iterator or IteratorAggregate. Traversable is the only class that has this behavior.

## Unknown errors

Here are some errors which are in the source code of PHP, but we could not reproduce. If you have experience, you can share it with us.

- `%s %s could not implement interface %s`
- `Cannot end an oplog without starting it` : oplog is for Operation Log.
- `huge_pages: thp unsupported on this platform`.

## Get ready for PHP 8.2

Hopefully, this quick tour in the new error messages of PHP 8.2 will help preparing the code for its own migration to PHP 8.2.

Since some of the checks are only available at execution time, it is worth running static analysis on it to spot potential errors. Exakat include the [Compatibility PHP 8.2](https://exakat.readthedocs.io/en/latest/Reference/Rulesets.html#compatibilityphp82) ruleset, with rules dedicated to PHP 8.2. They can run on PHP 8.1, so as to be ready for November 2022.

In the mean time, we'll keep an eye on the upcoming feature freeze.

Happy auditing.