Common causes
- A class assigns $this->something without declaring public, protected or private $something
- Code sets properties on another object from outside the class
- Older plugins, themes or libraries written before PHP 8.2
- A typo in a property name, so a new dynamic property is created instead of updating the declared one
- Readonly classes and enums, where a dynamic property throws an Error ('Cannot create dynamic property') instead of a notice
How to fix it
- Declare the property. Add the property to the class body, for example public ?string $fullName = null;. This is the proper fix and also helps IDEs and static analysis.
- Check for typos. Compare the property name in the message with the declared ones. A misspelled name such as $this->usrname creates a new property and is a real bug.
- Allow dynamic properties where intended. If the class is a flexible data container, add #[\AllowDynamicProperties] on the line above the class keyword. Classes that extend stdClass also allow them without the attribute.
- Use magic methods or an array. Implement __get() and __set() backed by a private array, or store arbitrary data in a property like private array $data = [];. Classes with __set() do not raise the deprecation.
- Update third-party code. If the file is in a plugin, theme or vendor folder, update it to a version that supports PHP 8.2. Do not edit vendor files directly, because updates overwrite them.
- Keep notices off-screen in production. Set display_errors = Off and log_errors = On. In WordPress, keep WP_DEBUG_DISPLAY false on live sites so deprecations only reach the log.
Three ways to fix it
<?php
// 1. Declare the property (preferred)
class User {
public ?string $fullName = null;
}
// 2. Explicitly allow dynamic properties
#[\AllowDynamicProperties]
class LegacyConfig {}
// 3. Use stdClass for free-form data
$row = new stdClass();
$row->anything = 'ok'; How to stop it happening again
- Declare all properties in class definitions
- Run PHPStan or Psalm, which flag access to undeclared properties
- Test against new PHP versions with error_reporting = E_ALL in development
- Scan legacy code for PHP 8.2 compatibility before upgrading