Handling 'Undefined array key' warnings in PHP8

Viewed 2406

Due to PHP8 escalating Undefined array key notices to warnings I have a problem with error logs being flooded due to our legacy code being written in a way that relied on PHP's implicit truthy/falsy-ness.

E.g.

if ($_POST['submit']) { ... } else { ... }
<input value="<?=$this_page['id']?>"> # in a shared add/edit form

Previously I was happy to suppress E_NOTICE, I'm not prepared to do this with E_WARNING.

I'm aware that the best solution would be refactoring code to make use of wrapper/abstraction classes to interact with superglobals and use object based models for database objects. Unfortunately, I have more than 100+ legacy applications to make PHP8 compliant inside of 6 months, therefore major refactoring isn't within scope.

I've tried using ArrayObject, which can solve some problems by overloading the offsetGet/Set, but this breaks compatibility with array_* functions and creates potential issues with third-party packages.

I'm wondering if anyone has developed a workaround for this yet, or has any ideas around a more drop in replacement. I'm open to pretty much any ideas other than major refactoring or shutting the projects down! Search/replace, project specific config, server level config, polyfills, I'm there.

1 Answers

If you're happy to do some find-and-replace, there are a few constructs which guarantee the same behaviour but without the Warning.

The most universal is the ?? null coalescing operator, which lets you convert an unset array key into an explicit null:

if ($_POST['submit']??null) { ... } else { ... }
<input value="<?=$this_page['id']??null?>"> 

More logically, the default in an echo statement is an empty string:

<input value="<?=$this_page['id']??''?>"> 

The logical default in an if statement is a boolean false, but perhaps more readable is the empty pseudo-function:

if (! empty($_POST['submit'])) { ... } else { ... }
Related