I have a order form with inputs like this:
<input type="text" name="booking[Sandwich][Roastbeef][qty]" />
<input type="text" name="booking[Sandwich][Cheese][qty]" />
<input type="text" name="booking[Pizza][Classic][qty]" />
<input type="text" name="booking[Pizza][Special][qty]" />
<input type="text" name="booking[Coffee][qty]" />
I'm having trouble looping through the arrays correctly.
Here is what kind of output I would like to have:
<h2>Sandwich</h2>
<p><strong>Roastbeef:</strong> 10</p>
<p><strong>Cheese:</strong> 5</p>
<hr>
<h2>Coffee</h2>
<p><strong>Quantity:</strong> 15</p>
If all the pizza input is empty, the heading "Pizza" should not be printed! The same with the "coffee" or "Sandwich" group. If the order does not contain anything in the group, the heading should not be printed.
I can't write specific tests for every input, as I have 200 of them.
Here is what I have tried to do:
$booking = $_POST['booking'];
//First check if there is one or more input that is not empty
if (!empty($booking)) {
foreach ($booking as $type => $items) {
if (count(array_filter($items))) {
$order .= "<hr>
<h2>" . ucfirst($type) . ":</h2>
";
}
foreach ($items as $name => $qty) {
if ($qty > "0"){
$order .= "<p><strong>" . ucfirst($name) . ":</strong> " . $qty . "</p>
";
}
}
}
}
This code only works when the array has a length of two keys. I can't seem to wrap my brain around as how to deal with other lengths. Any help would be great!
With the answer from @treegarden, I have almost what I need. Now I just need to have some sort of check if the "group" is empty, then the <h2>
should not be printed. if (count(array_filter($entry)))
works in not printing any thing if the group is empty, but just for those input that only have two keys.
if (!empty($booking)) {
foreach($booking as $key=>$entry) {
if (count(array_filter($entry))) {
echo "<h2>$key</h2>"; //Should only be printed if one or more inputs in the group are not empty
foreach($entry as $key=>$subEntry) {
if(is_array($subEntry) && $subEntry['qty'] > 0) {
echo "<p><strong>$key:</strong>" . $subEntry['qty'] . "</p>";
} elseif(!is_array($subEntry) && $subEntry > 0) {
echo "<p><strong>Quantity:</strong> $subEntry</p>";
}
}
echo '<hr/>';
}
}
}
Maybe try recursion, from example snippet:
<?php
class RecursiveArrayOnlyIterator extends RecursiveArrayIterator {
public function hasChildren() {
return is_array($this->current());
}
}
?>
else a simple forward way is to assume you have three or more nested loops, keep checking is $value in $kv using is_array(), which is done by invoking a function.
Try this
$booking = $_POST['booking'];
if (!empty($booking)) {
foreach ($booking as $type => $items) {
if (count(array_filter($items))) {
$order .= "<hr>
<h2>" . ucfirst($type) . ":</h2>
";
}
foreach ($items as $name => $qty) {
if (is_array($qty)) {
foreach ($qty as $qt) {
if ($qty > "0"){
$order .= "<p><strong>" . ucfirst($name) . ":</strong> " . $qt. "</p>
";
}
}
} else {
if ($qty > "0"){
$order .= "<p><strong>" . ucfirst($name) . ":</strong> " . $qty . "</p>
";
}
}
}
}
}