Can't seem to work out how to access data within an array that has other arrays within it.
My array looks like:
Array
(
[0] => Array
(
[_id] => 28
[serv_image] =>
[serv_name] => My Service
[slug] => my-service
[is_featured] =>
[_blocks] => Array
(
[0] => Array
(
[anchor_heading] => Mats Heading
[_block_type] => anchorHeading
[_block_id] => pe8t69
[_block_index] => 0
)
[1] => Array
(
[anchor_heading] => Another anchored heading
[_block_type] => anchorHeading
[_block_id] => pea49u
[_block_index] => 1
)
)
[_page] => *
[_pageID] => 1
[_sortvalue] => 1003
)
)
So far I've tried this without success:
foreach($services as $service) {
print_r($service['_blocks']['anchor_heading']);
}
This results in undefined index on anchor_heading.
UPDATE
I will have an unknown amount of these that I need to group together into a variable. How can I ensure I'm grabbing them all, no matter how many other times it's been entered?
You might use 2 times a foreach and echo the value of anchor_heading:
foreach($services as $service) {
foreach ($service["_blocks"] as $block) {
echo $block["anchor_heading"];
}
}
You have an array for each _block .. so you need an indexed access .. (or an inner iteration)
foreach($services as $service) {
print_r($service['_blocks'][0]['anchor_heading']);
print_r($service['_blocks'][1]['anchor_heading']);
}
(or an inner iteration)
foreach($services as $service) {
$blocks = $service['_blocks'];
foreach( $blocks as $block) {
print_r($block['anchor_heading']);
}
}
You can use the following to access the data within your array in a for loop:
print($service['_blocks'][0]['anchor_heading']);
Related
I want to be able to display the multidimensional associative array in a table. The arrays are created by Solarium API which is used for debugging any indexing issues. Each array has different number of arrays and keys.
I want it keep it in a way that it works with any number or arrays and keys. I started with using a foreach loop but I'm stuck at this point. How would I go about doing this?
Code I have so far:
foreach ($metadatas as $metadata) {
foreach($metadata as $type => $data) {
echo '<tr>';
echo '<td>'.$type.'</td>';
echo '<td>'.$data.'</td>';
echo '</tr>';
}
}
This is the array I get using print_r():
Solarium\QueryType\Extract\Query Object
(
[options:protected] => Array
(
[handler] => update/extract
[resultclass] => Solarium\QueryType\Extract\Result
[documentclass] => Solarium\QueryType\Update\Query\Document\Document
[omitheader] =>
[extractonly] =>
[uprefix] => ignored_
[commit] => 1
[file] => http://url.com/branch/files/2015/03/Client-Feedback-Form.doc
[document] => Solarium\QueryType\Update\Query\Document\Document Object
(
[boost:protected] =>
[modifiers:protected] => Array
(
)
[key:protected] =>
[fieldBoosts:protected] => Array
(
[id] =>
[site] =>
[description] =>
[url] =>
[title] =>
)
[version:protected] =>
[helper:protected] => Solarium\Core\Query\Helper Object
(
[placeHolderPattern:protected] => /%(L|P|T|)([0-9]+)%/i
[assembleParts:protected] =>
[derefencedParamsLastKey:protected] => 0
[query:protected] => Solarium\QueryType\Update\Query\Document\Document Object
*RECURSION*
)
[filterControlCharacters:protected] => 1
[fields:protected] => Array
(
[id] => 227-7653
[site] => Branch Name
[description] =>
[url] => http://url.ca/branch/files/2015/03/Client-Feedback-Form.doc
[title] => Client Feedback Form
)
)
)
[fieldMappings:protected] => Array
(
[content_type] => type
[author] => authors
[last_modified] => lastModifiedDate
[creation_date] => creationDate
[content] => content
)
[helper:protected] =>
[params:protected] => Array
(
)
)
I need more fake internet points to comment. So instead you get my poor answer. I'd try some sort of recursive function calling.
function someFunction($table , $array){
foreach($array as $key => $value){
if(is_array($value)){
someFunction(&$table, $value)
}
else {
//Add to your existing $table
}
}
return $table;
}
$table = someFunction("" , array());
obviously this is super simplistic view. But the idea is to keep passing your table deeper and deeper into the array. And eventually it will fall back out as you stop running into new arrays. I did something similar a while back passing around a DOMDocument() to build a super complex XML.
But this is only really useful when you don't know the possible size or depth of an array. If your array has keys, even if it's multidimensional, that you know will or won't exist and how deep they go. It's probably better to follow the answer in your comments and just build a nice HTML page.
Good luck.
As you can see from the first line of your output, it is not an array, but an OBJECT! And as you see in [options:protected] , it is protected variable, so you cannot access it from external foreach loop.
What you can do, is to declare a loop function inside that class:
class Query{
....
....
public function iterate(){
foreach ($this->options as $metadata) {
foreach($metadata as $type => $data) {
echo '<tr>';
echo '<td>'.$type.'</td>';
echo '<td>'.$data.'</td>';
echo '</tr>';
}
}
}
}
And then call it outside the class:
$object->iterate();
You can read more about this here: http://php.net/manual/en/language.oop5.iterations.php
I have an array, stored in $array, that with
print "<pre>";
print_r($array);
print "</pre>";
gives an output like this:
Array
(
[device] => Array
(
[0] => Array
(
[#attributes] => Array
(
[name] => Low volt light
[id] => 10
[type] => Z-Wave Switch Multilevel
[value] => 0
[address] => 00016922-018
[code] =>
[canDim] => True
[lastChange] => 26-07-2014 17:31:33
[firstLocation] => Kitchen
[secondLocation] => Main
)
)
[1] => Array
(
[#attributes] => Array
(
[name] => Light
[id] => 11
[type] => Z-Wave Switch Multilevel
[value] => 99
[address] => 00016922-019
[code] =>
[canDim] => True
[lastChange] => 31-07-2014 20:01:05
[firstLocation] => Bedroom
[secondLocation] => Main
)
)
I cannot find my way to access/display for example the value (in this case 0) of device with [id]=>10. What syntax would be the right one in php?
There's not an easy way to do this, without looping through the array.
e.g.
foreach ($array['devices'] as $device) {
if ($device['#attributes']['id'] === $idBeingSearchedFor) {
// Do something with $device.
}
}
Due to the #attributes array key, I'm guessing that this came from XML at some point: You might consider using Simple XML to parse it instead, as you could potentially use XPath then, which does support this type of access.
Alternatively again, you could reformat the array so it could be easily accessed by ID.
For example:
$formattedArray = array();
foreach ($array['devices'] as $device) {
$id = $device['#attributes']['id'];
$formattedArray[$id] = $device;
}
You could then access the device by its ID as follows:
$device = $formattedArray[$idBeingSearchedFor];
You could do it like that:
$id = 10;
$device = array();
foreach($array['device'] as $devices) {
if($devices['#attributes']['id'] == $id) {
$device = $devices['#attributes'];
break;
}
}
echo $device['value'];
Looks like SimpleXML, and if that is the case then those arrays are actually objects that, when put through print_r, look just like arrays. To access them, do the following:
Get straight to the data:
$name = $array->device[0]->attributes()->name;
Or loop through each of the attributes in the first device:
foreach ($array->device[0]->attributes() as $key => $value) {
// Do something with the data. $key is the name of the
// attribute, and then you have the $value.
}
Or you could loop through all the devices:
foreach ($array->device as $device) {
foreach ($device->attributes() as $key => $value) {
// Do something
}
}
It's simple ... try below...
print $array['device'][0]['#attributes']['id'];
or
print $array['device']['0']['#attributes']['id'];
I need to merge an array with value of parent array.
$testArr=unserialize('a:6:{s:5:"queue";a:2:{i:6;s:1:"5";i:5;s:1:"2";}s:3:"sum";a:2:{i:6;s:3:"765";i:5;s:3:"2.1";}s:7:"sumAccD";a:2:{i:6;s:3:"543";i:5;s:3:"3.1";}s:7:"sumAccC";a:2:{i:6;s:2:"54";i:5;s:3:"3.3";}s:7:"comment";a:2:{i:6;s:12:"test comment";i:5;s:6:"111222";}s:3:"yt0";s:0:"";}');
$ret = array();
foreach ($testArr as $pkey => $pval) {
if (is_array($pval)) {
foreach ($pval as $pvkey => $pvval) {
$ret[$pvkey] = array($pkey => $pvval);
}
}
}
echo '<pre>', print_r($ret), '</pre>';
In this case it prints out
Array
(
[6] => Array
(
[comment] => test comment
)
[5] => Array
(
[comment] => 111222
)
)
1
Unfortunally it print out only comment. I need to add other rows: queue,sum,sumAccD,sumAccC. Array must look like this:
Array
(
[6] => Array
(
[queue] => 5
[sum] => ''
....
[comment] => test comment
)
[5] => Array
(
[queue] => 2
[sum] => 2.1
....
[comment] => 111222
)
)
1
Please help merge them.
Thanks.
Look at this line:
$ret[$pvkey] = array($pkey => $pvval);
You're assigning the key to a new array every time, overwriting what was previously there.
In your case, 'comment' is the last key that is processed, so that's going to be the only key in the final array.
Instead of this, you could define a new array only once outside the inner for, like this:
$ret[$pvkey] = array();
And then assign your values to that array in the inner for loop as you would normally do (so no more creating arrays there!)
Problem solved by replacing
$ret[$pvkey] = array($pkey => $pvval);
with
$ret[$pvkey][$pkey] = $pvval;
Say I have the following:
Array(
[0] => Array
(
[id] => 1
[item] => first item
)
[1] => Array
(
[id] => 3
[item] => second item
)
[2] => Array
(
[id] => 5
[item] => third item
)
)
I want to delete the item with id = 5. I know I can loop through the array and unset, but I'm hoping for a more direct/efficient solution.
If you cannot make the IDs the keys of the outer array (then you could simply use unset($arr[5]);), looping over the array is indeed the way to dg.
foreach($arr as $key => $value) {
if($value['id'] === 5) {
unset($arr[$key]);
break;
}
}
Another option would be using array_filter - that's less efficient though since it creates a new array:
$arr = array_filter($arr, function($value) {
return $value['id'] !== 5;
});
Why don't you create the array with the keys set as the ID's? E.g:
Array(
[1] => Array
(
[id] => 1
[item] => first item
)
[3] => Array
(
[id] => 3
[item] => second item
)
[5] => Array
(
[id] => 5
[item] => third item
)
)
You can then write:
<?php
unset($array[5]); // Delete ID5
?>
For Multi level nested array
<?php
function remove_array_by_key($key,$nestedArray){
foreach($nestedArray as $k=>$v){
if(is_array($v)){
remove_array_by_key($key,$v);
} elseif($k==$key){
unset($nesterArray[$k]);
}
}
return $nestedArrat;
}
?>
The most efficient way would be to have 2 arrays.
ID => Index
Index => Object (your current array)
Search for ID in your ID => Index helper array and the value will be the Index for your main array, then unset them both.
Using PHP I'm trying to remove an element from an array based on the value of the element.
For example with the following array:
Array
(
[671] => Array
(
[0] => 1
[1] => 100
[2] => 1000
)
[900] => Array
(
[0] => 15
[1] => 88
}
)
I'd like to be able to specify a value of on of the inner arrays to remove. For example if I specified 100 the resulting array would look like:
Array
(
[671] => Array
(
[0] => 1
[2] => 1000
)
[900] => Array
(
[0] => 15
[1] => 88
}
)
My first thought was to loop through the array using foreach and unset the "offending" value when I found it, but that doesn't seem to reference the original array, just the loop variables that were created.
Thanks.
foreach($array as $id => $data){
foreach($data as $index => $offending_val){
if($offending_val === 100){
unset($array[$id][$index]);
}
}
}
You can use:
array_walk($your_array, function(&$sub, $key, $remove_value) {
$sub = array_diff($sub, array($remove_value));
}, 100);
Couple of ideas:
You could try array_filter, passing in a callback function that returns false if the value is the one you want to unset. Using your example above:
$new_inner_array = array_filter($inner_array, $callback_that_returns_false_if_value_100)
If you want to do something more elaborate, you could explore the ArrayIterator class of the SPL, specifically the offsetUnset() method.