0

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

3 Answers 3

1

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>";
                }
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

This works quite well, but displays the data of only a single invoice. I guess that's because you've used foreach($data[0]. I tried changing that to $data but that still wont solve the problem. I need to display the data of all invoices in there...
Then you just add another loop since $data as whole is an array, see the updated code.
1

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

Comments

0

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

2 Comments

Can it be done all in one loop without specifying key names?
Yes - if you are willing to use array_map

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.