Fixing PHP 8.1 "Passing null to parameter" deprecation warnings
Problem Overview
PHP 8.1 introduced significant changes to type handling, particularly around passing null
values to string parameters of core functions. Previously, PHP would silently convert null
to an empty string when passed to functions like htmlspecialchars()
, trim()
, strlen()
, and many others. With PHP 8.1, this behavior is now deprecated and generates warnings.
The core issue is that many legacy codebases relied on this implicit conversion, making migration to PHP 8.1 potentially challenging without extensive code modifications.
Recommended Solutions
1. Null Coalescing Operator
The most straightforward fix is to use PHP's null coalescing operator (??
) to provide a default empty string value:
// Before:
htmlspecialchars($variable);
trim($input);
// After:
htmlspecialchars($variable ?? '');
trim($input ?? '');
2. Explicit Type Casting
For cases where you're confident the value should be a string, explicit casting is another option:
// Before:
trim($value);
// After:
trim((string)$value);
WARNING
Note that casting will convert null
to an empty string, but will also convert other types like integers, booleans, and objects to their string representations, which may not always be desired.
3. Custom Wrapper Functions
Create wrapper functions that handle null values consistently:
function safe_trim(?string $value): string
{
return trim($value ?? '');
}
function safe_htmlspecialchars(?string $string, int $flags = ENT_COMPAT, ?string $encoding = null, bool $double_encode = true): string
{
return htmlspecialchars($string ?? '', $flags, $encoding, $double_encode);
}
4. Automated Code Refactoring with Rector
For large codebases, consider using Rector to automate the migration process. Rector includes the NullToStrictStringFuncCallArgRector
rule that can automatically add the necessary type casts:
// Before Rector:
mb_strtolower($value);
// After Rector:
mb_strtolower((string) $value);
Advanced Solutions
Error Handling Approach
For temporary solutions during migration, you can customize error handling to suppress deprecation warnings:
// In your bootstrap or error handling file
set_error_handler(function($severity, $message, $file, $line) {
$allowed_deprecations = [
"trim(): Passing null to parameter",
"htmlspecialchars(): Passing null to parameter",
// Add other deprecation messages you want to suppress
];
foreach ($allowed_deprecations as $deprecation) {
if (strpos($message, $deprecation) !== false) {
return true; // Suppress the warning
}
}
// Let other errors be handled normally
return false;
});
DANGER
Suppressing errors should only be a temporary measure during migration. Always address the root cause in your code rather than permanently suppressing warnings.
Framework-Specific Solutions
For specific frameworks like Magento or WordPress:
Magento - Custom error handler modification:
// In vendor/magento/framework/App/ErrorHandler.php
public function handler($errorNo, $errorStr, $errorFile, $errorLine)
{
if (E_DEPRECATED === $errorNo) {
// Log deprecation warnings instead of throwing exceptions
$this->logger->warning("PHP Deprecation: $errorStr in $errorFile on line $errorLine");
return true;
}
// Rest of original error handling...
}
WordPress - PHPCS configuration:
<!-- In phpcs.xml -->
<ini name="error_reporting" value="E_ALL & ~E_DEPRECATED" />
Best Practices for Migration
- Prioritize critical code paths - Fix functions that handle user input and output first
- Use static analysis tools - PHPStan and Psalm can help identify problematic code
- Test thoroughly - Ensure your changes don't introduce new bugs
- Update third-party dependencies - Check for library updates that address PHP 8.1 compatibility
- Address root causes - Instead of just patching symptoms, consider why null values are appearing where strings are expected
Common Functions Affected
The following core PHP functions are commonly affected by this change:
trim()
,ltrim()
,rtrim()
htmlspecialchars()
,htmlentities()
strlen()
,mb_strlen()
strpos()
,stripos()
,strrpos()
substr()
,mb_substr()
strtolower()
,strtoupper()
urlencode()
,rawurlencode()
json_encode()
(when passing null as value to encode)
Migration Strategy
Step-by-step migration plan
- Assessment - Run your code with error reporting set to
E_ALL
to identify all deprecation warnings - Prioritization - Focus on high-traffic code paths and security-sensitive functions first
- Implementation - Apply the null coalescing operator or type casting as appropriate
- Testing - Thoroughly test all affected functionality
- Verification - Re-run with full error reporting to ensure all warnings are resolved
Remember that while PHP 8.1 only emits deprecation warnings for these issues, PHP 9.0 will likely make them errors, so addressing them now ensures future compatibility.