How to echo data from a Multi-Dimensional Array in PHP? - php

I need to echo/return the data to the page like this:
Catalog: 251-2010
Gauge: 20g
Length: 10cm
Tip Size: 10mm
Here is the array called $vararray. It contains several different arrays of product variation data:
array(3) {
[0]=> array(1) {
["251-2010"]=> array(1) {
["Gauge"]=> string(3) "20g"
}
}
[1]=> array(1) {
["251-2010"]=> array(1) {
["Length"]=> string(4) "10cm"
}
}
[2]=> array(1) {
["251-2010"]=> array(1) {
["Tip Size"]=> string(4) "10mm"
}
}
}
array(3) {
[0]=> array(1) {
["600-VR1620"]=> array(1) {
["Chart Type"]=> string(14) "Shirt"
}
}
[1]=> array(1) {
["600-VR1152"]=> array(1) {
["Chart Type"]=> string(13) "Trousers"
}
}
[2]=> array(1) {
["600-VR16211"]=> array(1) {
["Chart Type"]=> string(13) "Socks"
}
}
}
I need something like this:
$vargroup = array();
foreach ($vararray as $vitems) {
$varmeta = array_values($vararray);
foreach ($varmeta as $metain => $vardetails) {
vargroup[$metain]['catalog'] = $vardetails['Catalog'];
vargroup[$metain]['gauge'] = $vardetails['Gauge'];
vargroup[$metain]['length'] = $vardetails['Length'];
vargroup[$metain]['tipsize'] = $vardetails['Tip Size'];
}
$vars_profile = '';
foreach ($vargroup as $vgrp) {
$vars_profile .= $vgrp[catalog] . '<br>' . $vgrp[gauge] . '<br>' . $vgrp[length] . '<br>' . $vgrp[tipsize];
}
}
return $vars_profile;
I'm having a lot of trouble getting it right. Here is how I need it to look:
Catalog: 251-2010
Gauge: 20g
Length: 10cm
Tip Size: 10mm
Catalog: 600-VR1620
Chart Type: Shirt
Catalog: 600-VR1152
Chart Type: Trousers
Catalog: 600-VR16211
Chart Type: Socks

You can't get all of Catalog, Gauge, Length, and Tip Size from the same $vardetails element, they're in different elements of the array. You need to drill into each element to get its key and value.
You can create $vars_profile in the loop that's processing the original array, you don't need $vargroup.
To show the category only once, use a variable to hold the last value. Only output the category line when this field changes.
$vars_profile = '';
$last_metain = null;
foreach ($vararray as $vitem) {
foreach ($vitem as $metain => $vardetails) {
if ($metain != $last_metain) {
$vars_profile .= "<p>\nCatalog: $metain<br>\n";
$last_metain = $metain;
}
foreach ($vardetails as $key => $value) {
$vars_profile .= "$key: $value<br>\n";
}
}
}
return $vars_profile;

Related

How to group a multidimensional array by multiple subarray values?

I checked this question and answers:
How to group a multidimensional array by a particular subarray value?
He wanted to group results by 'level'. But how would you do it to group it by 'level' first and then by 'type'?
Its pretty straight forward. Loop through $items array. Get each item's level and type and if they are not set yet, initialize them with an empty array. Then just push the "cust" value into the array.
I have given the code below.
I am assuming "$items" is an array which contains the input.
$g = [];
foreach($items as $k => $v) {
$l = $v["level"];
$t = $v["type"];
$c = $v["cust"];
if(!isset($g[$l])) {
$g[$l] = [];
}
if(!isset($g[$l][$t])) {
$g[$l][$t] = [];
}
$g[$l][$t][] = [
"cust" => $c
];
}
var_dump($g);
The output of this code would be like below:
array(3) {
[1]=>
array(1) {
["standard"]=>
array(2) {
[0]=>
array(1) {
["cust"]=>
string(6) "XT8900"
}
[1]=>
array(1) {
["cust"]=>
string(6) "XT8944"
}
}
}
[3]=>
array(1) {
["premier"]=>
array(2) {
[0]=>
array(1) {
["cust"]=>
string(6) "XT8922"
}
[1]=>
array(1) {
["cust"]=>
string(6) "XT8816"
}
}
}
[7]=>
array(1) {
["standard"]=>
array(1) {
[0]=>
array(1) {
["cust"]=>
string(6) "XT7434"
}
}
}
}
[P.S.]: You can also use sort to solve this problem easily. That's another way of solving this problem.

Loop through multidimensional array and write to file for each parent array

I'm looping through a multidimensional array of field groups and sub fields Using this code:
<?php
$field_groups = acf_get_field_groups();
foreach( $field_groups as $field_group ) {
$acf_groups = acf_get_fields_by_id( $field_group['ID'] );
foreach($acf_groups as $group) {
echo '<pre>';
var_dump($group);
echo '</pre>';
}
}
Which gets me this array:
array(20) {
["group"]=>
string(6) "button"
["sub_fields"]=>
array(5) {
[0]=>
array(23) {
["name"]=>
string(11) "button_text"
}
[1]=>
array(19) {
["name"]=>
string(11) "button_link"
}
}
}
array(20) {
["group"]=>
string(2) "h1"
["sub_fields"]=>
array(8) {
[0]=>
array(23) {
["name"]=>
string(9) "font_size"
}
[1]=>
array(26) {
["name"]=>
string(15) "font_size_units"
}
}
}
What I'm trying to do is print out a file with the sub_field values for each of the $group arrays ('button' and 'h1' respectively).
So for example, I want to end up with in this case 2 files:
button.php
h1.php
button.php would have:
button_text
button_link
h1.php would have:
font_size
font_size_units
I can get the two files to print out within that loop however the h1.php file includes the button sub_fields values, so:
button_text
button_link
font_size
font_size_units
How can I split the files up by the parent array and then print out a file for each group with its respective sub_fields values?
Figured it out...needed an additional grouped array to group the elements by the key in the nested array, in my case $sub['label'].
This isn't pretty or the most elegant but it works.
<?php
$field_groups = acf_get_field_groups();
foreach( $field_groups as $field_group ) {
$acf_groups = acf_get_fields_by_id( $field_group['ID'] );
$grouped = array();
foreach ($acf_groups as $group) {
$subs = $group['sub_fields'];
foreach($subs as $sub) {
$grouped[$group['label']][] = $sub['label'];
}
foreach ($grouped as $key => $items) {
// print by group here.
}
}
}

How can I detect the most inner array keys of a multidimensional array?

array(1) {
["farm"]=>
array(2) {
["folder1"]=>
array(2) {
["horse"]=>
array(1) {
["fred.jpg"]=>
string(30) "farm/folder1/horse/fred.jpg"
}
["cat"]=>
array(1) {
["john.jpg"]=>
string(28) "farm/folder1/cat/john.jpg"
}
}
["folder2"]=>
array(1) {
["cat"]=>
array(2) {
["sam.jpg"]=>
string(27) "farm/folder2/cat/sam.jpg"
["cat"]=>
array(1) {
["john.jpg"]=>
string(32) "farm/folder2/cat/cat/john.jpg"
}
}
}
}
}
Is it possible to detect only the most inner array keys?
foreach($array as $key => $value){
if ($key == $most_inner_array) {
echo $key;
}
}
So that in this case the result would be:
fred.jpg
john.jpg
sam.jpg
john.jpg
You can go through your array recursively and print the key if the value is not an array.
In case of just printing a value like in your example, you can do it with just array_walk_recursive() without any condition. Something like:
array_walk_recursive($your_array, function($value, $key) {
echo $key . "\n";
});

create php array using simpleXMLobject

I'm trying to get this array ($resdata) with object(SimpleXMLElement) into a php array:
$resdata =
array(59) {
[0]=> ...
[10]=> object(SimpleXMLElement)#294 (28) {
["reservation_id"]=> string(7) "8210614"
["event_id"]=> string(6) "279215"
["space_reservation"]=> array(2) {
[0]=> object(SimpleXMLElement)#344 (9) {
["space_id"]=> string(4) "3760"
["space_name"]=> string(9) "205"
["formal_name"]=> string(33) "Center" }
[1]=> object(SimpleXMLElement)#350 (9) {
["space_id"]=> string(4) "3769"
["space_name"]=> string(9) "207"
["formal_name"]=> string(32) "Right" } } }
}
I've tried:
$res = (array)$resdata;
$reservation = $res['reservation'];
$result = array();
foreach ($reservation as $key => $value){
$res = array($value);
$spid = $res[0]->space_reservation->space_id;
echo $value->event_id."<br />";
echo $spid."<br />";
}
This only outputs the first space_id and I need to get all the space_ids within "space_reservation" array. Not all records will have multiple space_ids. Any help pointing me in the right direction is appreciated. Not sure if I should use xpath but I need to re-write my foreach statement regardless.
I was hoping to be able to literally convert all references to "object(SimpleXMLElement)#_ (#)" to "array(#)"
[10]=> array (28) {
["reservation_id"]=> string(7) "8210614"
["event_id"]=> string(6) "279215"
["space_reservation"]=> array(2) {
[0]=> array (9) {
["space_id"]=> string(4) "3760"
["space_name"]=> string(9) "205"
["formal_name"]=> string(33) "Center" }
[1]=> array (9) {
["space_id"]=> string(4) "3769"
["space_name"]=> string(9) "207"
["formal_name"]=> string(32) "Right" } } }
}
the function in my cakephp 1.3 controller is this:
$xml = simplexml_load_string($string);
$this->data['events']= $xml->children();
$resdata = $this->data['events'];
$this->set('resdata',$resdata);
I think this should do what you are looking for:
foreach ($resdata as $res) {
echo $res->event_id . '<br />';
foreach ($res->space_reservation as $reservation) {
echo $reservation->space_id . '<br />';
}
}
Googled it and found a general solution for any SimpleXMLElement to array conversion:
function xml2array($xml) {
$arr = array();
foreach ($xml as $element) {
$tag = $element->getName();
$e = get_object_vars($element);
if (!empty($e)) {
$arr[$tag] = $element instanceof SimpleXMLElement ? xml2array($element) : $e;
}
else {
$arr[$tag] = trim($element);
}
}
return $arr;
}

Traverse non-numerical indexes of an array

Think I'm missing a basic concept. I want to generate html by traversing through a few different arrays of data. They don't use numbers as indexes so numerical looping doesn't work. I cant figure out how to use a foreach() here either. How can I traverse $price and $description when the indexes aren't numbers?
Sample:
$traverser= 0;
while($traverser < $number_of_records)
{
print $traverser . " - " . $price[$traverser] . "<br />";
print $description[$traverser];
$traverser++;
}
Partial Sample of the Array Structure:
object(phpQueryObject)#2799 (13) { ["documentID"]=> string(32) "1d62be942498df890cab4ccb78a007a2" ["document"]=> &object(DOMDocument)#3 (0) { } ["charset"]=> &string(5) "utf-8" ["documentWrapper"]=> &object(DOMDocumentWrapper)#2 (17) { ["document"]=> &object(DOMDocument)#3 (0) { } ["id"]=> string(32) "1d62be942498df890cab4ccb78a007a2" ["contentType"]=> string(9) "text/html" ["xpath"]=> &object(DOMXPath)#4 (0) { } ["uuid"]=> int(0) ["data"]=> array(0) { } ["dataNodes"]=> array(0) { } ["events"]=> array(0) { } ["eventsNodes"]=> array(0) { } ["eventsGlobal"]=> array(0) { } ["frames"]=> array(0) { } ["root"]=> &object(DOMElement)#5 (0) { } ["isDocumentFragment"]=> &bool(true) ["isXML"]=> bool(false) ["isXHTML"]=> bool(false) ["isHTML"]=> bool(true) ["charset"]=> &string(5) "utf-8" } ["xpath"]=> &object(DOMXPath)#4 (0) { } ["elements"]=> array(560) { [0]=> object(DOMElement)#2239 (0) { } [1]=> object(DOMElement)#2240 (0) { } [2]=> object(DOMElement)#2241 (0) { } [3]=> object(DOMElement)#2242 (0) { } [4]=> object(DOMElement)#2243 (0) { } [5]=> object(DOMElement)#2244 (0) { } [6]=> object(DOMElement)#2245 (0) { } [7]=> object(DOMElement)#2246 (0) { } [8]=> object(DOMElement)#2247 (0) { }
Since it looks like you need the array keys as well, since you're referencing multiple different arrays, you want the $a as $k => $v syntax for foreach:
foreach($description as $key => $desc)
{
print $key . " - " . $price[$key] . "<br />";
print $desc;
}
You can take your pic as to how you want to iterate them:
<?php
$ary = array( // demo array
'apple' => 'Apple',
'orange' => 'Orange',
'grape' => 'Grape'
);
// show the structure
var_dump($ary); echo "\r\n";
// use a foreach with the key and value
foreach ($ary as $key => $val)
printf("%s => %s\r\n", $key, $val);
echo "\r\n";
// just get the raw keys
$keys = array_keys($ary);
var_dump($keys); echo "\r\n";
output:
array(3) {
["apple"]=>
string(5) "Apple"
["orange"]=>
string(6) "Orange"
["grape"]=>
string(5) "Grape"
}
apple => Apple
orange => Orange
grape => Grape
array(3) {
[0]=>
string(5) "apple"
[1]=>
string(6) "orange"
[2]=>
string(5) "grape"
}
There's always array_map & array_walk.
I'm not sure I get the question, but it's really as simple as:
<?php
$array = array('foo', 'bar');
foreach ($array as $element) {
echo "{$element}\n";
}
This should output "foo" and "bar".

Categories