DEV Community

WPTOOLS
WPTOOLS

Posted on

Creation of dynamic property is deprecated: fixing the most common PHP 8.2 warning in WordPress

If your WordPress site moved to PHP 8.2 or newer, there's a good chance your debug.log is full of this:

PHP Deprecated: Creation of dynamic property My_Plugin::$settings is deprecated
in /wp-content/plugins/my-plugin/my-plugin.php on line 18
Enter fullscreen mode Exit fullscreen mode

First, the reassuring part: this does not break your site. It's a deprecation, which means PHP is telling you this will become a problem in a future version. Your code still runs exactly as before.

But it's noisy, it hides real errors in the log, and it's easy to fix once you know what it means.

What PHP is complaining about

A "dynamic property" is a property you set on an object without declaring it in the class:

class My_Plugin {
    public function __construct() {
        $this->settings = get_option( 'my_plugin' ); // $settings was never declared
    }
}
Enter fullscreen mode Exit fullscreen mode

PHP allowed this silently for decades. Since PHP 8.2 it's deprecated, because a typo like $this->setings would quietly create a new property instead of failing.

Fix 1: declare the property (the right fix)

class My_Plugin {
    public $settings;

    public function __construct() {
        $this->settings = get_option( 'my_plugin' );
    }
}
Enter fullscreen mode Exit fullscreen mode

One line, and the warning is gone. Your editor also understands the class better now. Use this whenever you own the code.

Fix 2: the attribute (quick fix for legacy classes)

Sometimes a big old class sets properties all over the place and you can't refactor it today:

#[\AllowDynamicProperties]
class Legacy_Plugin {
    // lots of old code that adds properties dynamically
}
Enter fullscreen mode Exit fullscreen mode

This tells PHP the class uses dynamic properties on purpose. It's safe on older PHP versions too: before PHP 8, a line starting with # is just a comment.

Fix 3: magic methods (when the properties really are dynamic)

If the property names genuinely aren't known in advance, store them yourself:

class My_Plugin {
    private $data = array();

    public function __get( $name ) {
        return $this->data[ $name ] ?? null;
    }

    public function __set( $name, $value ) {
        $this->data[ $name ] = $value;
    }
}
Enter fullscreen mode Exit fullscreen mode

Classes with __get and __set don't trigger the warning.

Two cases that don't need fixing

  • stdClass objects (which WordPress core uses a lot) are exempt.
  • Code you didn't write. If the path points to a plugin from wordpress.org, don't edit it: your change disappears on the next update. Update the plugin first, and if the warning is still there, report it on the plugin's support forum with the exact log line.

Keep visitors from seeing it

Log warnings, don't display them:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
Enter fullscreen mode Exit fullscreen mode

Finding these before your host upgrades PHP

The log only shows warnings for code that actually ran, meaning pages someone visited. To see everything in advance, I built a free plugin, CompatNav – PHP Upgrade Checker. It reads every plugin and theme and separates what will break from deprecations like this one, for PHP 8.0 to 8.5. It runs on your own server and never changes code.

Disclosure: I'm the developer. It's free with no upsell inside. If it reports something wrong on your site, tell me in the comments.

What other PHP 8.x warnings are filling your logs? I'm happy to help decode them below.

Top comments (0)