Norman
Norman

Reputation: 6365

PHP Looping through a multidimensional array

I've got this array that gets created using jquery and is passed to a php script. It's json that gets decoded using json_decode. I can loop through most of it, but there's a part near the items bit that gets me stuck. Can you help?

This is output using print_r();

Array
(
    [0] => Invoice
)
Array
(
    [0] => Array
        (
            [Invoice] => Array
                (
                    [header] => Array
                        (
                            [date] => 20-Jan-2020
                            [buyer] => Buyer 1
                            [order] => 006896
                        )

                    [items] => Array
                        (
                            [0] => Array
                                (
                                    [name] => Name 1
                                    [quantity] => Quantity 1
                                    [rate] => 199.99
                                )

                            [1] => Array
                                (
                                    [name] => Name 2
                                    [quantity] => Quantity 2
                                    [rate] => 99.99
                                )

                        )

                )

        )

    [1] => Array
        (
            [Invoice] => Array
                (
                    [header] => Array
                        (
                            [date] => 10-Jan-2020
                            [buyer] => Buyer 2
                            [order] => 007033
                        )

                    [items] => Array
                        (
                            [0] => Array
                                (
                                    [name] => Item A
                                    [quantity] => 25
                                    [rate] => 19.99
                                )

                            [1] => Array
                                (
                                    [name] => Item B
                                    [quantity] => 30
                                    [rate] => 29.99
                                )

                        )

                )

        )

)

PHP

$data = json_decode($_POST['data'],true);

echo '<pre>';
foreach ($data as $key=>$a) {
    //print_r($key);print_r($a);
    foreach ($a as $key=>$b) {
        //print_r($key);print_r($b);
        foreach ($b as $key=>$c) {
            print_r($key);print_r($c);
            foreach ($c as $key=>$d) {
                //print_r($d);
            }   
        }
    }
}
echo '</pre>';

I'm trying to get the output as follows:

date 20-Jan-2020
buyer Buyer 1
order 006896

name Name 1
quantity Quantity 1
rate 199.99

name Name 2
quantity Quantity 2
rate 99.99

Upvotes: 0

Views: 100

Answers (3)

IVO GELOV
IVO GELOV

Reputation: 14269

Perhaps something like this:

$data = json_decode($_POST['data'],true);

$invoice = $data[0]['Invoice'];
echo 'date '.$invoice['header']['date']."\n";
echo 'buyer '.$invoice['header']['buyer']."\n";
echo 'order '.$invoice['header']['order']."\n\n";

foreach($invoice['items'] as $item)
{
  echo 'name '.$item['name']."\n";
  echo 'quantity '.$item['quantity']."\n";
  echo 'rate '.$item['rate']."\n\n";
}

@Norman:

Can it be done all in one loop without specifying key names?

Assuming that the input is

$data = [
  [
    'Invoice' => [
      'header' => [
        'date' => '20-Jan-2020',
        'buyer' => 'Buyer 1',
        'order' => '006896',
      ],
      'items' => [
        [
          'name' => 'Name 1',
          'quantity' => 'Quantity 1',
          'rate' => 199.99
        ],
        [
          'name' => 'Name 2',
          'quantity' => 'Quantity 2',
          'rate' => 99.99
        ],
      ],
    ],
  ],
  [
    'Invoice' => [
      'header' => [
        'date' => '22-Jan-2020',
        'buyer' => 'Buyer 2',
        'order' => '006891',
      ],
      'items' => [
        [
          'name' => 'Name 3',
          'quantity' => 'Quantity 3',
          'rate' => 155.55
        ],
        [
          'name' => 'Name 5',
          'quantity' => 'Quantity 5',
          'rate' => 222.22
        ],
      ],
    ],
  ]
];

then with the single loop below

foreach($data as $v)
{
  $invoice = array_shift($v);
  $header = array_shift($invoice);
  print_item($header);
  $body = array_shift($invoice);
  array_map('print_item', $body);
}

function print_item($item)
{
  array_map('print_chunk',array_keys($item),$item);
  echo "\n";  
}

function print_chunk($key,$value)
{
  echo "$key: $value\n";
}

you will get the following output

date: 20-Jan-2020
buyer: Buyer 1
order: 006896

name: Name 1
quantity: Quantity 1
rate: 199.99

name: Name 2
quantity: Quantity 2
rate: 99.99

date: 22-Jan-2020
buyer: Buyer 2
order: 006891

name: Name 3
quantity: Quantity 3
rate: 155.55

name: Name 5
quantity: Quantity 5
rate: 222.22

Upvotes: 0

RiWe
RiWe

Reputation: 377

This could help:

$oldDepth = 0; // this is for the new lines
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($data));
for ($iterator->rewind(); $iterator->valid(); $iterator->next()) {
    if ($oldDepth && $oldDepth > $iterator->getDepth()) {
        echo PHP_EOL . PHP_EOL; // not on first round and only when we get to a new invoice
    }
    elseif ($iterator->key() == 'name') {
        echo PHP_EOL; // before every position assuming 'name' is always first
    }
    $oldDepth = $iterator->getDepth();
    echo $iterator->key();
    echo ': ';
    echo $iterator->current();
    echo PHP_EOL;
}

Demo: https://3v4l.org/EWpKE

Upvotes: 1

Syed
Syed

Reputation: 563

This is how it will be done without specifying the key name:

foreach($data[0] as $key => $value) {
        // Loop through invoice
        foreach($value as $key => $value) {
            // Loop through header and iterms
            foreach($value as $key => $value) {
                // Check if the value has an array
                if (is_array($value)) {
                    echo "<br>";
                    foreach($value as $key => $value) {
                        print_r($key);
                        echo ": ";
                        print_r($value);
                        echo "<br>";
                    }
                } else {
                    print_r($key);
                    echo ": ";
                    print_r($value);
                    echo "<br>";
                }
            }
        }
    }

enter image description here

Edit:

  foreach($data as $key => $value) {
    // New Loop
    foreach($value as $key => $value) {
        // Loop through invoice
        foreach($value as $key => $value) {
            // Loop through header and iterms
            foreach($value as $key => $value) {
                // Check if the value has an array
                if (is_array($value)) {
                    echo "<br>";
                    foreach($value as $key => $value) {
                        print_r($key);
                        echo ": ";
                        print_r($value);
                        echo "<br>";
                    }
                } else {
                    print_r($key);
                    echo ": ";
                    print_r($value);
                    echo "<br>";
                }
            }
        }
    }
}

Upvotes: 1

Related Questions