← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · updated 7d
← Back to glossary

Accessing Undeclared Properties (PHP 8.2+)

PHP PHP 8.2+ Intermediate
debt(d5/e3/b3/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list phpstan and psalm as the tools that catch this, and the common_mistakes note that PHPStan level 6+ is required. These are specialist static analysis tools, not default linters or compiler errors. In production the deprecation notice is an E_DEPRECATED warning that may be swallowed depending on error reporting configuration, making it silent without tooling.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix indicates declaring all class properties explicitly and optionally adding #[AllowDynamicProperties] as a temporary measure. This is more than a one-line swap (you must audit and declare properties across a class), but it is still localised within a single class at a time rather than spanning multiple files as a cross-cutting refactor.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). The issue applies per-class where dynamic properties are used. The burden falls on the maintainer of each affected class to declare properties or add the attribute. It applies broadly across web, cli, and queue-worker contexts but is addressed class by class rather than imposing a system-wide architectural weight. It does not impose a persistent tax on unrelated code paths.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception field directly states that developers believe dynamic properties are removed in PHP 8.2, when in fact they are only deprecated (E_DEPRECATED) with the fatal Error arriving in PHP 9. This contradicts the common expectation that a 'deprecated' feature from a major version is immediately fatal, and the silent typo-creates-new-property behaviour (from common_mistakes) further contradicts how property assignment is expected to work in strictly-typed languages.

About DEBT scoring →

TL;DR

PHP 8.2 deprecated dynamic (undeclared) properties — PHP 9 will make them an error. Declare all properties explicitly or use AllowDynamicProperties.

Explanation

Before PHP 8.2, classes silently accepted any property assignment ($obj->foo = 'bar' even if $foo wasn't declared). PHP 8.2 deprecated this with E_DEPRECATED. PHP 9 will throw an Error. Exceptions: stdClass and objects using #[AllowDynamicProperties] still allow dynamic properties. __get()/__set() magic methods also still work. The migration path: run static analysis to find all dynamic property access, add explicit typed declarations, or add #[AllowDynamicProperties] to legacy classes as a transitional step.

Common Misconception

Dynamic properties are removed in PHP 8.2 — they're only deprecated (E_DEPRECATED). The fatal Error comes in PHP 9.

Why It Matters

Dynamic properties are a frequent source of typos creating invisible new properties instead of setting existing ones — strict declarations prevent silent data loss.

Common Mistakes

  • Setting a property with a typo — creates a new dynamic property silently instead of throwing.
  • Not adding #[AllowDynamicProperties] to legacy value objects during migration.
  • Not running PHPStan level 6+ which flags dynamic property access.

Code Examples

✗ Vulnerable
class User {
    public string $name;
}
$u = new User();
$u->nmae = 'Paul'; // Typo: creates dynamic property 'nmae', $name stays unset
// PHP 8.2: Deprecated, PHP 9: Fatal Error
✓ Fixed
class User {
    public string $name;
    public string $email;
    // All properties explicitly declared — typos caught at PHP level
}

// For legacy classes needing time to migrate:
#[\AllowDynamicProperties]
class LegacyDto {
    // Allowed for now, migrate later
}

Added 22 Mar 2026
Views 75
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 2 pings T 1 ping W 0 pings T 0 pings F 0 pings S 2 pings S 0 pings M 0 pings T 0 pings W 0 pings T 2 pings F 1 ping S 0 pings S 0 pings M 0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Perplexity 9 ChatGPT 8 Amazonbot 7 Scrapy 5 Ahrefs 4 SEMrush 4 Unknown AI 3 Google 3 PetalBot 3 Majestic 2 Twitter/X 2 Meta AI 1 Applebot 1 Brave Search 1
crawler 47 crawler_json 5 pre-tracking 1
🧱 FUNDAMENTALS — new to this? Start with the ground floor.
PHP php A server-side scripting language that generates web pages and APIs — the code runs on the server, and only its output (usually HTML or JSON) reaches the browser.

PHP is often the first server-side language people meet, and understanding its execution model — script starts fresh on every request, no memory between requests — explains most of how the web backend works: sessions, databases, and caching all exist to bridge that per-request amnesia.

💡 Start with PHP 8.x, declare(strict_types=1), and PDO — skip any tutorial that mentions mysql_query().

Ask Codex about PHP →
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Declare all class properties explicitly. Run PHPStan level 6+ to find dynamic property access. Add #[AllowDynamicProperties] as a temporary measure on legacy classes.
📦 Applies To
PHP 8.2+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
\$[a-zA-Z]+->
Auto-detectable: ✓ Yes phpstan psalm
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Medium ✓ Auto-fixable Fix: Medium Context: Class


✓ schema.org compliant