Monday, 27 August 2018

PHP foreach with multidimensional array does not print all values

I have a very simple multidimensional array and some PHP code. The code should print the p_id values, but it does not do it. Do I really have to add one foreach more or is there other ways?
And here is the array:
Array (
  [2764] => Array (
    [status] => 0

    [0] => Array (
      [p_id] => 2895
    )

    [1] => Array (
      [p_id] => 1468
    )
  )

  [5974] => Array (
    [status] => 0

    [0] => Array (
      [p_id] => 145
    )

    [1] => Array (
      [p_id] => 756
    )
  )
)

Here is my PHP code:
foreach($arr as $innerArray)
  foreach($innerArray as $key => $value)
    echo $key . "=>" . $value . "<br>";

It prints:
status=>0
0=>Array
1=>Array
status=>0
0=>Array
1=>Array

This simple call to array_walk_recursive() produces the output requested in the question:
array_walk_recursive(
    $arr,
    function ($value, $key) {
        echo $key . "=>" . $value . "<br>";
    }
);

But it doesn't make much sense as the output mixes the values of status with the values of p_id.
I would go for a more structured display using the original code with a little more meaning for the names of the variables:
foreach ($arr as $catId => $catInfo) {
    // Category ID and details; use other names if I'm wrong
    printf("Category: %d (status: %s)\n", $catId, $catInfo['status'] ? 'active' : 'inactive');
    foreach ($catInfo as $key => $value) {
        if ($key == 'status') {
            // Ignore the status; it was already displayed
            continue;
        }

        foreach ($value as $prodInfo) {
            printf("    Product ID: %d\n", $prodInfo['p_id']);
        }
    }
}


The structure of the input array tells me you should first fix the code that generates it. It should group all the products (the values that are now indexed by numeric keys) into a single array. It should look like this:
$input = array(
    '2764' => array(
        'status' => 0,
        'products' => array(
            2895 => array(
                'p_id' => 2895,
                'name' => 'product #1',
                // more product details here, if needd
            ),
            1468 => array(
                'p_id' => 1468,
                'name' => 'product #2',
            ),
            // more products here
        ),
    // more categories here
),

Then the code that prints it will look like this:
foreach ($arr as $catId => $catInfo) {
    // Category ID and details; use other names if I'm wrong
    printf("Category: %d (status: %s)\n", $catId, $catInfo['status'] ? 'active' : 'inactive');
    foreach ($catInfo['products'] as $prodInfo) {
        printf("    %s (ID: %d)\n", $prodInfo['name'], $prodInfo['p_id']);
        // etc.
    }
}

0 comments:

Post a Comment