Migrating from PHP 7 to PHP 8
debt(d3/e5/b5/t5)
Closest to 'default linter catches' (d3). Rector, phpcs, and php-cs-fixer (all listed in detection_hints.tools) can identify deprecated functions like each() and create_function(), and Rector can automate many fixes. The automated:yes flag confirms tooling catches the common cases, though subtle type coercion changes may slip through.
Closest to 'touches multiple files / significant refactor' (e5). The quick_fix mentions multiple categories of changes: running Rector, fixing type coercion issues, removing deprecated functions, and checking Composer dependencies. While individual fixes are small, a real migration touches many files across the codebase and requires extensive testing per the term's guidance.
Closest to 'persistent productivity tax' (b5). The migration applies across all PHP contexts (web, cli, queue-worker) per applies_to, affecting the entire codebase. While it's a one-time migration effort rather than ongoing decay, the choice of when to migrate shapes development velocity — staying on PHP 7 blocks new features and security patches, while migrating requires coordinated effort across all components.
Closest to 'notable trap / documented gotcha' (t5). The misconception field explicitly states developers wrongly assume 'PHP 7 code runs unchanged on PHP 8.' The why_it_matters section highlights silent behavioral changes like comparison operator associativity changes and match expressions throwing errors. These are documented gotchas that most PHP developers learn, but first-timers often discover through production bugs.
TL;DR
Explanation
PHP 8.0 breaking changes from 7.x: (1) Arithmetic with non-numeric strings throws TypeError (no silent coercion). (2) match expression available (not breaking but replaces switch patterns). (3) each() removed — use foreach. (4) create_function() removed — use closures. (5) Deprecated @ error suppression changes. (6) PDO::FETCH_LAZY changed. PHP 8.1: (1) Passing null to non-nullable params deprecated. (2) Implicit float-int coercion emits deprecation. (3) Enums — not breaking but replace patterns. PHP 8.2: dynamic properties deprecated. Full list: php.net migration guides. Run php8-compat tool or Rector before upgrading.
Common Misconception
Why It Matters
Common Mistakes
- Not running Rector before upgrading — misses automatable fixes.
- Not testing with PHP 8's stricter type handling — silent 7.x bugs become errors.
- Not checking Composer dependencies for PHP 8 compatibility before upgrading.
When To Use
- When upgrading a PHP 7.x application to PHP 8.0 or later.
- When security patches for PHP 7.4 end (November 2022) and moving to actively supported versions.
- When you want access to PHP 8 features (match, enums, named arguments, constructor promotion).
- Before deploying to hosting environments that only support PHP 8+.
Code Examples
// Breaks in PHP 8:
$result = '5 apples' + 3; // TypeError in 8 (was 8 in 7)
each($array); // Fatal — removed
// Before upgrading:
// 1. Run: composer check-platform-reqs
// 2. Run: vendor/bin/rector process --dry-run
// 3. Test with: php -d error_reporting=E_ALL index.php
// Fix arithmetic:
$count = (int)$str + 3;
// Fix each():
foreach ($array as $key => $value) { }