Fix “Creation of dynamic property … is deprecated” in WordPress

By CompatNav · Published · Last reviewed · 3 min read

Short answer

The notice means a class stores a value in a property it never declared, like $this->limit = 5. It’s a deprecation notice from PHP 8.2: the code still works. Site owners: update the plugin or theme named in the path, or send one line of the message to its developer, and log notices instead of displaying them. Developers: declare the property in the class (public $limit;), the clean fix that works on every PHP version. If the class genuinely needs properties created on the fly, add #[\AllowDynamicProperties] above it, or implement __get() and __set().

The notice, on PHP 8.1 and 8.2

A reviews widget sets two properties in its constructor without declaring them. PHP 8.1 is silent; PHP 8.2 adds a notice per property, and the widget still shows its title:

wp-content/plugins/recent-reviews/includes/class-reviews-widget.php

<?php
class Reviews_Widget {
    public function __construct() {
        $this->limit = 5;          // never declared in the class
        $this->title = 'Latest reviews';
    }
}

$widget = new Reviews_Widget();
echo $widget->title, ' (', $widget->limit, ")\n";

Output on PHP 8.1.34

Latest reviews (5)

Output on PHP 8.2.34

Deprecated: Creation of dynamic property Reviews_Widget::$limit is deprecated in /var/www/html/wp-content/plugins/recent-reviews/includes/class-reviews-widget.php on line 4

Deprecated: Creation of dynamic property Reviews_Widget::$title is deprecated in /var/www/html/wp-content/plugins/recent-reviews/includes/class-reviews-widget.php on line 5
Latest reviews (5)

php.net, in the PHP 8.2 deprecations: “The creation of dynamic properties is deprecated, unless the class opts in by using the #[\AllowDynamicProperties] attribute.” (php.net)

For site owners: three steps

  1. Find the plugin or theme: the folder after wp-content/plugins/ or wp-content/themes/ in the path, here recent-reviews.
  2. Update it (Dashboard → Updates); a newer version may already declare its properties.
  3. Still there? Send one line of the message to its developer, and log notices instead of displaying them meanwhile.

For developers: the three fixes

1. Declare the property

The fix that fits almost every case. Same output, no notice, on PHP 7.4, 8.2 and 8.5:

wp-content/plugins/recent-reviews/includes/class-reviews-widget.php

<?php
class Reviews_Widget {
    public $limit;
    public $title;

    public function __construct() {
        $this->limit = 5;
        $this->title = 'Latest reviews';
    }
}

$widget = new Reviews_Widget();
echo $widget->title, ' (', $widget->limit, ")\n";

Output on PHP 7.4.33

Latest reviews (5)

Output on PHP 8.2.34

Latest reviews (5)

Output on PHP 8.5.11

Latest reviews (5)

2. Allow dynamic properties

For a class designed to hold arbitrary properties, add the attribute above it:

#[\AllowDynamicProperties]
class Reviews_Widget {
    // …
}

php.net: “This attribute is used to mark classes that allow dynamic properties.” (php.net) On PHP 7.4 the line starts with #, so it’s read as a comment and changes nothing there.

3. Magic methods

A class that implements __get() and __set() decides itself what happens with unknown properties, without a notice. Useful when the class stores them in an array of its own.

Find them before you upgrade

The assignments are in the code, so a check that reads it finds every one, while your site still runs PHP 8.1:

CompatNav, free on wordpress.org, reports them per plugin and theme. All the details, including properties set from outside the class and stdClass: “Creation of dynamic property … is deprecated”.

Key takeaways

  • A PHP 8.2 deprecation notice: the property is still created, the page works.
  • Fix 1, the right one in most cases: declare the property in the class.
  • Fix 2: #[\AllowDynamicProperties] above the class, for classes designed to hold arbitrary properties.
  • Fix 3: __get() and __set(), when the class should control those properties itself.
  • Site owners don’t edit plugin files: update, or send the message to the developer.

Frequently asked questions

Do I have to fix it before switching to PHP 8.2 or later?

No. It’s a notice: your site works with it. Log notices instead of showing them, and let plugin updates fix it.

Why do I see the notice twice for one class?

One notice per undeclared property. A class that sets two such properties gives two lines.

Which fix is best?

Declaring the properties, in almost every case. The attribute is for classes that store arbitrary data on purpose; it also works on PHP 7.4, where it’s read as a comment.

Check your own site before you upgrade

CompatNav is a free WordPress plugin. It reads the code of your plugins and themes on your own server and tells you, in plain words, what will break and what will only show notices on the PHP version you choose. It never changes your code. It can’t see problems that only appear while code runs with real data, so a quick check of your site after the upgrade still matters.

Get CompatNav on wordpress.org How it works

Sources

About the code examples: each output is the real output of the code shown, run with the official PHP builds, without a php.ini, with all errors reported and displayed. Only the file path was replaced by a neutral server path.