Php8 Undefined variable

Upgrading packages to PHP8, I’m seeing tons of Undefined variable errors. These are errors now when a variable has not been declared. I found using “?? null” in statements is an easy way to solve the problem.

<?php   echo $form->checkbox('title', 1, $title) ?> FAILS
<?php   echo $form->checkbox('title', 1, $title ?? null) ?> WORKS

 $args['show_category'] = ($args['show_category']  ? '1' : '0';  FAILS
 $args['show_category'] = ($args['show_category'] ?? null) ? '1' : '0'; Works

I’m not sure if this is the best practice in dealing with it, it seemed easier than declaring all the variables as many are not always passed from the controller. I’m interested in how other people are dealing with this. Also, I’d like to suggest we compile a list of fixes for PHP8 issues people are going to run into.

Thanks

  1. I have suggested that in another topic - to add info about common PHP8 errors (and how to fix tem) in almost non-existing “Migration” page in docs. Since solutions for them are fairly “trivial”, if you have minimal PHP experience.
    It should be really helpful for many people.

  2. I would call declaring variables/properties at the top of block controller (and then adding $this->set('xxx', $this->xxx) wherever needed) a good practice, since:

  • you will get hints from Editor when typing $this->… etc.
  • you will not get errors, when you actually need to use those variables in controller methods.

Nonetheless, it doesn’t matter much how you fix it, if you don’t use $this->xxx in other methods in controller.
In general, I think fixing variables in view.php is “sufficient” quick fix, using coalescing operator (??) especially.

Keep in mind that $title ?? null is an equivalent of isset(title) ? title : null.
isset() will check if variable is defined (if it is something different than null). So if variable was defined at some point as empty string '' or 0 or "0" it would still pass check.

Another option is:

!(empty($title)) ? $title : null

which is an equivalent of

(isset($title) and $title) ? $title : null

which is similar to isset(), but in addition ''/0/"0" values will not pass check.

  1. Second common php8 error is “Undefined array key”. This one can be usually fixed by checking if specific array element exists, like changing from:
if ($array['example_key']) {}

to

if (isset($array['example_key']) and $array['example_key']) {}
  1. Your code
<?php echo $form->checkbox('title', 1, $title ?? null) ?> WORKS
// This is more than fine for quick/easy fix. But I would consider declaring properties in controller class and passing them by $this->set('variable', $this->variable). Whatever you prefer.
$args['show_category'] = ($args['show_category'] ?? null) ? '1' : '0'; Works
// This feels sketchy. It can be one of this edge cases that actually works, but it feels 
// overcomplicated/strange/hard to read for me as it is written right now.
// Instead I would just do something like that:
$args['show_category'] = !empty($args['show_category']) ? '1' : '0'; 
// or
$args['show_category'] = (isset($args['show_category']) and $args['show_category']) ? '1' : '0'; 
// or that
// remember that if "$args['show_category']" was an empty string/0 it would still return "1")
$args['show_category'] = isset($args['show_category']) ? '1' : '0'; 
1 Like

Hi,
I have been doing the Undefined array key the way suggested, that one pops up a lot, isset has come in handy too. I was thinking adding $this->set(‘xxx’, $this->xxx) in the block controllers, it seemed like a lot of extra code and the coalescing operator seemed to do the trick for a quick fix.

Thanks for your input, hopefully we can all share are fixes here and help each other out,