Search code examples
phpnullphp-8.1

Passing null to non-nullable internal function parameters - Updating Existing Code Base to php 8.1


I am just getting started on upgrading my code to be php 8.1 compatible. I have many pieces of code where I am passing potentially null values to internal functions.

if (strlen($row) > 0) {
   ...
} 

Where $row comes from a source that may have null values (e.g. a query). This can generate a deprecation warning; in this case:

Deprecated: strlen(): Passing null to parameter #1 ($string) of type string is deprecated

I'm looking for the easiest most time efficient way to handle upgrading this code, for example fixes where global search and replaces are possible. It seems that type casting the variable I pass to an internal function works without changing functionality.

error_reporting(E_ALL);
$row = null;

if (strlen((string) $row) > 0) {
   ...
}

Aside from the moral aspects of coding this way, are there issues with this approach for internal functions? Are there better ways (other than completely rewriting the code and handling nulls differently)? I prefer this solution backwards compatible to v7.4, although I could possibly live with 8.0 compatibility.

I am aware my user defined functions have other choices.


Solution

  • If you're explicitly trying to handle the case of null, then a slightly cleaner fix would be strlen($row ?? '') using the "null coalescing operator".

    In most cases, the two are probably equivalent but with strict_types=1 in effect, they behave differently if the value is some other type that can be cast to string:

    declare(strict_types=1);
    $row = 42;
    echo strlen($row); // TypeError: must be of type string, int given
    echo strlen((string) $row); // Succeeds, outputting '2'
    echo strlen($row ?? ''); // TypeError: must be of type string, int given
    

    On the other hand, note that the ?? operator is based on isset, not === null, so an undefined variable will behave differently:

    declare(strict_types=1);
    $row = [];
    echo strlen($row['no_such_key']); // Warning: Undefined array key; TypeError: must be of type string, null given
    echo strlen((string) $row['no_such_key']); // Warning: Undefined array key; outputs '0'
    echo strlen($row['no_such_key'] ?? ''); // No warning, just outputs '0'
    

    If you care about that case, the most directly equivalent code to the old behaviour is rather more verbose:

    echo strlen($row === null ? '' : $row);