The attribute opts a class out of the deprecation, which is occasionally correct and is usually a way of deferring a rename.
#[AllowDynamicProperties]
class LegacyBag
{
// a class whose whole purpose is arbitrary attributes,
// written before stdClass was idiomatic
}
// it is inherited by subclasses, which is convenient and
// makes the exemption wider than the annotation suggests.
// the honest alternatives:
// declare the properties
// extend stdClass
// hold an array and expose it through __get
Inheritance of the attribute is the part that makes it dangerous as a quick fix: applying it to a base model exempts every model in the application, which is exactly what somebody under deadline pressure will do. Where it is legitimate — a genuine property bag from before stdClass was conventional — it deserves a comment explaining why, because the next reader will assume it was applied to make a build pass.