Migrating from PHP 4 to PHP 5
debt(d5/e5/b5/t7)
Closest to 'specialist tool catches' (d5). Tools like Rector and phpcs (cited in detection_hints) can detect PHP 4 patterns like 'var $' declarations and old-style constructors, but the semantic changes in object behavior (pass-by-reference vs pass-by-value) require more careful analysis beyond simple pattern matching.
Closest to 'touches multiple files / significant refactor' (e5). The quick_fix describes replacing var keywords, adding constructors/type hints, wrapping errors in try/catch, and testing object assignment code — this is a systematic refactor touching many files across a codebase, but not a full architectural rewrite.
Closest to 'persistent productivity tax' (b5). Legacy PHP 4 code that hasn't been migrated imposes ongoing maintenance costs. The applies_to scope covers web and cli contexts broadly, and unmigrated code creates friction for developers unfamiliar with PHP 4 patterns, but it doesn't define system architecture.
Closest to 'serious trap' (t7). The misconception explicitly states 'PHP 4 code mostly works in PHP 5 — most code does run but object semantics changed, which can cause subtle bugs where shared objects were relied upon.' This contradicts how developers familiar with PHP 5+ expect objects to behave, creating silent semantic bugs rather than crashes.
TL;DR
Explanation
Key PHP 4→5 breaking changes: (1) Object semantics: assignments now copy the handle (reference semantics) — $b = $a no longer clones. Existing =& $obj patterns still work but are now redundant. (2) var → public/protected/private. (3) try/catch available — replace die() and trigger_error(). (4) SPL data structures available. (5) SimpleXML, SOAP, DOM extensions redesigned. (6) mysql_ still works but deprecated (removed PHP 7). Migration tools: PHP_CompatInfo, PHPCS with compatibility sniffs. Test with E_ALL | E_STRICT error reporting to find issues.
Common Misconception
Why It Matters
Common Mistakes
- Not testing object mutation after migration — shared object behaviour changed.
- Keeping var keyword — works but signals unmodernised code.
- Not converting to try/catch — missed opportunity for better error handling.
Code Examples
// PHP 4 class:
class User {
var $name;
var $email;
function getName() { return $this->name; }
}
// PHP 5 style:
class User {
private string $name;
private string $email;
public function __construct(string $name, string $email) {
$this->name = $name;
$this->email = $email;
}
public function getName(): string { return $this->name; }
}