PHP Deprecated (8.x) Failing CI - Deprecations Promoted to Errors
PHP 8.x added many deprecations (nullable implicit, dynamic properties, passing null to non-nullable internals). When error_reporting includes E_DEPRECATED and an error handler escalates notices, or a test runner fails on deprecations, these warnings become hard CI failures.
What this error means
CI fails with "PHP Deprecated: ... in ..." lines, often "Creation of dynamic property" or "Passing null to parameter of internal function is deprecated", even though the app runs. A custom error handler or the test runner converts the deprecation into a failure.
PHP Deprecated: Creation of dynamic property App\Dto::\$extra is deprecated in
/app/src/Dto.php on line 22
# error handler converts E_DEPRECATED to an exception -> CI step exits non-zeroCommon causes
New 8.x deprecations now trigger
Dynamic properties, implicit nullable params, and passing null to internal functions became deprecated in PHP 8.x. Upgrading the runner PHP surfaces them all at once.
An error handler escalates E_DEPRECATED
A set_error_handler that throws on any reported level, or a test runner configured to fail on deprecations, turns each deprecation into a fatal failure.
How to fix it
Fix the deprecation at its source
Declare properties (or use #[AllowDynamicProperties]), make nullable params explicit, and stop passing null to internals.
class Dto
{
public ?string \$extra = null; // declare instead of dynamic
}Scope error_reporting deliberately for the run
If you must defer fixes, exclude E_DEPRECATED rather than silencing all errors - and track the debt.
php -d error_reporting='E_ALL & ~E_DEPRECATED' vendor/bin/phpunitAudit every deprecation before upgrading PHP
- Run the suite on the new PHP with deprecations visible but non-fatal first.
- Collect the full list, then fix dynamic properties and null-to-internal calls.
- Re-enable strict deprecation failure once the list is clear.
How to prevent it
- Fix deprecations as they appear instead of masking E_DEPRECATED long-term.
- Declare all properties; use #[AllowDynamicProperties] only as a deliberate bridge.
- Run the suite against the next PHP version in a matrix to catch deprecations early.