$invoice->totall = 250; One extra letter. No error, no warning. A second property appears, the real total stays null, and the bug surfaces three screens later as “total is empty sometimes”.

I have hunted this exact bug. Twice. Both times it took hours, because the write looks correct and the read looks correct. They just disagree on one letter.

PHP 8.2 lands in December, and the deprecation that will touch the most code is this one. Writing to an undeclared property becomes deprecated. In some future major it becomes an error. For fifteen years it was legal:

class Invoice
{
    public $total;
}

$invoice = new Invoice();
$invoice->totall = 250; // new property, created silently

This week I ran one older codebase on an 8.2 release candidate with deprecations logged. The harvest: two real typos, both in code “that worked for years”. It worked the way a broken clock works. The rest were objects used as bags, $row->computed = ... on things fetched from here and there.

The fixes, in order of preference. Declare the property, which is what should have happened in the first place. If the class really carries arbitrary keys, that is an array or a real __get/__set pair. stdClass stays exempt anyway. For third-party or legacy classes you cannot touch now, #[AllowDynamicProperties] on the class keeps the old behavior. Treat that attribute as a bookmark, not as a fix.

You do not have to wait for December. PHPStan flags undeclared property access today, on any PHP version. Turn the rule on, fix what it finds, and 8.2 becomes a non-event.

Two typos in one evening of reading a log. That is a better rate than my two hunts.