Reputation: 281
I have a multi dimensional array from which I'm trying to pull values from using foreach
.
It's retrieved JSON format, so I've used json_decode
to convert it to an associative array.
The array contains pricing information for various products. The problem I'm struggling with is that it contains multiple nested arrays for each product.
Because of this, I'm not sure how I integrate this into foreach
.
Array $arr:
Array
(
[result] => success
[totalresults] => 3
[products] => Array
(
[product] => Array
(
[0] => Array
(
[pid] => 2
[gid] => 2
[type] => other
[name] => Shared Hosting
[description] => Shared Cloud
[module] => custom server
[paytype] => onetime
[pricing] => Array
(
[GBP] => Array
(
[prefix] => £
[suffix] => GBP
[msetupfee] => 0.00
[qsetupfee] => 0.00
[ssetupfee] => 0.00
[asetupfee] => 0.00
[bsetupfee] => 0.00
[tsetupfee] => 0.00
[monthly] => 0.00
[quarterly] => -1.00
[semiannually] => -1.00
[annually] => -1.00
[biennially] => -1.00
[triennially] => -1.00
)
)
[customfields] => Array
(
[customfield] => Array
(
)
)
[configoptions] => Array
(
[configoption] => Array
(
[0] => Array
(
[id] => 2
[name] => Years
[type] => 2
[options] => Array
(
[option] => Array
(
[0] => Array
(
[id] => 2
[name] => 1 Year
[recurring] =>
[pricing] => Array
(
[GBP] => Array
(
[msetupfee] => 0.00
[qsetupfee] => 0.00
[ssetupfee] => 0.00
[asetupfee] => 0.00
[bsetupfee] => 0.00
[tsetupfee] => 0.00
[monthly] => 69.00
[quarterly] => 0.00
[semiannually] => 0.00
[annually] => 0.00
[biennially] => 0.00
[triennially] => 0.00
)
)
)
[1] => Array
(
[id] => 5
[name] => 2 Years
[recurring] =>
[pricing] => Array
(
[GBP] => Array
(
[msetupfee] => 0.00
[qsetupfee] => 0.00
[ssetupfee] => 0.00
[asetupfee] => 0.00
[bsetupfee] => 0.00
[tsetupfee] => 0.00
[monthly] => 138.00
[quarterly] => 0.00
[semiannually] => 0.00
[annually] => 0.00
[biennially] => 0.00
[triennially] => 0.00
)
)
)
[2] => Array
(
[id] => 8
[name] => 3 Years
[recurring] =>
[pricing] => Array
(
[GBP] => Array
(
[msetupfee] => 0.00
[qsetupfee] => 0.00
[ssetupfee] => 0.00
[asetupfee] => 0.00
[bsetupfee] => 0.00
[tsetupfee] => 0.00
[monthly] => 276.00
[quarterly] => 0.00
[semiannually] => 0.00
[annually] => 0.00
[biennially] => 0.00
[triennially] => 0.00
)
)
)
[3] => Array
(
[id] => 11
[name] => 4 Years
[recurring] =>
[pricing] => Array
(
[GBP] => Array
(
[msetupfee] => 0.00
[qsetupfee] => 0.00
[ssetupfee] => 0.00
[asetupfee] => 0.00
[bsetupfee] => 0.00
[tsetupfee] => 0.00
[monthly] => 552.00
[quarterly] => 0.00
[semiannually] => 0.00
[annually] => 0.00
[biennially] => 0.00
[triennially] => 0.00
)
)
)
[4] => Array
(
[id] => 14
[name] => 5 Years
[recurring] =>
[pricing] => Array
(
[GBP] => Array
(
[msetupfee] => 0.00
[qsetupfee] => 0.00
[ssetupfee] => 0.00
[asetupfee] => 0.00
[bsetupfee] => 0.00
[tsetupfee] => 0.00
[monthly] => 1104.00
[quarterly] => 0.00
[semiannually] => 0.00
[annually] => 0.00
[biennially] => 0.00
[triennially] => 0.00
)
)
)
)
)
)
)
)
)
The above section is repeated from [product]
for each product ID ([pid]
) - I couldn't fit the whole array in the post, so here's a link to it - http://pastebin.com/0qgh5scG
What I want to achieve is pulling the name description, and EACH Monthly* price for each product ID [pid]
in the array, into an array of it's own with that arrays variable name being the associated [pid]
.
*(The monthly price is actually an annual price, it's just a weird manner in which the module stores the data in the database)
I've experimented with foreach
:
$arr = json_decode($jsondata, true); # Decode JSON String
foreach ($arr['products']['product'] as $num) {
$pid = $num['pid'];
$yearlycosts = $arr['configoptions']['configoption']['0']['options']['option'][0]['pricing']['GBP']['monthly'];
echo $pid;
echo $yearlycosts;
}
The product ID, retrieves ok, but how on earth do I pull the multiple [name]
and related multiple [monthly]
values for each product ID [pid]
?
Do I require a foreach
within in my existing foreach
?
Eventually I want to pass these values to new arrays, with each array named after it's corresponding [pid]
value. But I think that's a separate question/challenge for me.
I hope I've made sense above. I'm new to arrays, and in searching through quite a few examples didn't find any that had an array as complex as the one above, or that had sections that are uniquely named.
Upvotes: 0
Views: 836
Reputation: 1229
First off, where did this $pricing variable come from? You were using $num at first.
And yes, just a nested foreach loop will do the trick like so:
$arr = json_decode($jsondata, true); # Decode JSON String
foreach ($arr['products']['product'] as $num) {
$pid = $num['pid'];
echo "Product ID: ".$pid."\n";
echo "Options: \n"
$i = 1;
foreach($num['configoptions']['configoption']['0']['options']['option'] as $option)
{
$name = $option['name'];
$yearlycosts = $option['pricing']['GBP']['monthly'];
echo " - Option ".$i.": ".$name." ($".$yearlycosts.")\n";
++$i;
}
}
Upvotes: 1
Reputation: 1229
First off, looking at the array structure, 'CUSTOMFIELDS' is just an empty key, it doesn't contain 'CONFIGOPTION'.
So this:
echo $k['CUSTOMFIELDS'][CONFIGOPTIONS][CONFIGOPTION][OPTIONS][OPTION][NAME];
echo $k['CUSTOMFIELDS'][CONFIGOPTIONS][CONFIGOPTION][OPTIONS][OPTION][MONTHLY];
Needs to look like this:
echo $k[CONFIGOPTIONS][CONFIGOPTION][OPTIONS][OPTION][NAME];
echo $k[CONFIGOPTIONS][CONFIGOPTION][OPTIONS][OPTION][MONTHLY];
I think I'd probably try to first fix all the names of the indexes and make my life easy from there. I would traverse the whole array with this function:
function traverseArray($array)
{
// Loops through each element. If element again is array, function is recalled. If not, result is echoed.
foreach($array as $key=>$value)
{
if (is_array($value))
{
traverseArray($value);
} else {
if (preg_match("/[0-9]/", $key) && !isset($array[preg_replace("[0-9]", "", $key)]))
$array[preg_replace("[0-9]", "", $key)] = $value;
}
}
}
This function (Found it here: http://snipplr.com/view/10200/ and modified it for the current question) will go through the whole array, each level of it, and remove numbers from end of array keys IF the key without the number doesn't exist. Reason for that is some of those arrays contain multiple arrays with keys like OPTION, OPTION12, OPTION43, etc. If the key without the number within the same level exists, it will leave it alone. Now that takes all the numbers away from keys like PRICING, GBP, etc. We're only gonna be left with some OPTION keys that will have numbers at the end. Then we will be able to go:
traverseArray($arr); // Goes through arrray and removes random numbers unless not possible
foreach($k['CONFIGOPTIONS']['CONFIGOPTION']['OPTIONS'] as $option) {
echo $option['NAME'];
echo $option['PRICING']['GBP']['MONTHLY'];
}
Try it out. I think that should work.
P.S.: They should really figure something out on their end about that API because that's a horrible array to work with. There's no reason for that.
Upvotes: 0