Skip to content

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.

1. Null Coalescing Operator

The most straightforward fix is to use PHP's null coalescing operator (??) to provide a default empty string value:

php
// 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:

php
// 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:

php
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:

php
// 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:

php
// 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:

php
// 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:

xml
<!-- In phpcs.xml -->
<ini name="error_reporting" value="E_ALL &amp; ~E_DEPRECATED" />

Best Practices for Migration

  1. Prioritize critical code paths - Fix functions that handle user input and output first
  2. Use static analysis tools - PHPStan and Psalm can help identify problematic code
  3. Test thoroughly - Ensure your changes don't introduce new bugs
  4. Update third-party dependencies - Check for library updates that address PHP 8.1 compatibility
  5. 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
  1. Assessment - Run your code with error reporting set to E_ALL to identify all deprecation warnings
  2. Prioritization - Focus on high-traffic code paths and security-sensitive functions first
  3. Implementation - Apply the null coalescing operator or type casting as appropriate
  4. Testing - Thoroughly test all affected functionality
  5. 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.