skip to Main Content

I am preparing to migrate a complex website to PHP 8.1. I have a page with 2 nested loops which fail with:

Fatal error: Uncaught TypeError: count(): Argument #1 ($value) must be of type Countable|array, null given

I have created a test page using the offending loops:

<?php

$prop_info=array();

$propRates=array();

$propRates[0]=  
    array(
    'title'=>'Test Cottage',
    'thirty_night_min' => 0,
    'id' => 1426225,
    'date_new' => 05-22
    );
$propRates[1]=  
    array(
    'title'=>'Maunawai Hale',
    'thirty_night_min' => 0,
    'id' => 1591525,
    'date_new' => 05-24
    );  
$propRates[2]=  
    array(
    'title' => 'Pines 4050',
    'thirty_night_min' => 0,
    'id' => 1503333,
    'date_new' => '05-24'
    );  
    

$prop_info[1]=$propRates;

echo('<pre>');

print_r($prop_info);

echo('</pre>');

// Offending loops
for($b=1;$b=(count($prop_info[$b])+1);$b++){
    
    for($i=0;$i<count($prop_info[$b]);$i++){
        
        echo('b: '.$b.' i '.$i.' Title: '.$prop_info[$b][$i]['title'].' ID: '.$prop_info[$b][$i]['id'].'<br />');
        
    }

}

?>

I’ve tried using is_countable function, but am not sure how to integrate it in these for loops. Any help would be much appreciated. Pardon my bad logic or sloppy coding. I will provide more info if needed.
Thanks

3

Answers


  1. You can’t count NULL because NULL is not an array.

    So; Use the ?? operator so that if the value is NULL, then this can be replaced with an empty array; this will result in the count($value) = 0 which is equivilant to if the item being counted is not an array.

    I have also applied similar logic for the print statement.

    for($b=1;$b=(count($prop_info[$b]??[])+1);$b++){
        
        for($i=0;$i<count($prop_info[$b]??[]);$i++){
            
            echo('b: '.$b.' i '.$i.' Title: '.($prop_info[$b][$i]['title']??'').' ID: '.($prop_info[$b][$i]['id']??'').'<br />');
            
        }
    
    }
    

    EDIT:

    for some reason this tweak does resolve the issue but there seems a severe memeory leak overhead in the core source code you’ve given. This is due to the for loops involved.

    Error: The output is over 10MB and too big to display in the browser. This can be caused by a loop, too much errors displayed or simply by using too much data for in a browser window.

    So recommend to use foreach rather than for loops, so that you can only cycle over the contents within the array rather than arbitarily counting values that might or might not exist.

    Login or Signup to reply.
  2. A solution is to cast whatever you are counting explicitly as an array:

    for($b=1;$b=(count( (array) $prop_info[$b])+1);$b++){
    

    The error actually hints that.

    Login or Signup to reply.
  3. Use foreach loops for array’s. The for loop in your example has a condition mistake!

    // Offending loops
    for($b=1;$b=(count($prop_info[$b])+1);$b++){
        
        for($i=0;$i<count($prop_info[$b]);$i++){
            
            echo('b: '.$b.' i '.$i.' Title: '.$prop_info[$b][$i]['title'].' ID: '.$prop_info[$b][$i]['id'].'<br />');
            
        }
    
    }
    

    Should be:

    // Offending loops
    for($b = 0 ; $b < count($prop_info) ; $b++){
        
        for($i = 0 ;$i < count($prop_info[$b]) ; $i++){
            
            echo('b: '.$b.' i '.$i.' Title: '.$prop_info[$b][$i]['title'].' ID: '.$prop_info[$b][$i]['id'].'<br />');
            
        }
    
    }
    

    With foreach:

    // Offending loops
    foreach($prop_info as $key => $info) {
                    
        echo('b: '.$key.' Title: '.$info['title'].' ID: '.$info['id'].'<br />');
            
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search