I have an array like this in PHP:
$array = array(
'main0' => array(
'level0' => array('0'=>'value_1'),
'level1' => array(
'0' => 'value_2',
'1' => 'value_3',
),
'level2' => array('0'=>'value_445')
),
'main1' => array(
'level0' => array('0'=>'value_1'),
'level1' => array('0'=>'value_12'),
'level2' => array(
'0' => 'value_2',
'1' => 'value_3',
),
'level3' => array('0'=>'value_5')
),
);
This array will be dynamic, to many mainkeys and levels, each level also have dynamic amount of values.
My problem is, I'm trying to echo each of the array level in select option html markup. I've tried foreach ($array[][] as $value) but with no luck. How to achieve this in PHP?
EDIT
Solved my problem using 3 foreach, might be not the cleanest solution but it works. My solution in blade php:
<?php $data = Product::GetCategories(); ?>
#if ($data != null)
#foreach ($data as $item)
<optgroup label="{{ $item[0][0] }}">
#foreach ($item as $level)
#foreach ($level as $v)
<option value="{{ $v }}">{{ $v }}</option>
#endforeach
#endforeach
</optgroup>
#endforeach
#endif
If you don't really care about manipulating the array items, and all you want is to see the result on screen, you may use: print_r($array);
If you do need to do something with the array items, then here is a recursive function(myRecursiveFunction), and a normal function that is executed on a non-array (myNormalFunction) to illustrate the process.
function myRecursiveFunction($array) {
foreach($array as $key=>$value) {
if(is_array($value)) {
myRecursiveFunction($value);
}
myNormalFunction($value);
}
}
For starters use something like DomDocument to manipulate html in php.
Other than that try:
foreach ($array as $key => $value ) {
print $key . " " . $value;
}
For further nesting keep is_array in mind, so now your code becomes
foreach ($array as $key => $value ) {
print $key . " " . $value;
if(is_array($value)) {
//do something with this array
}
}
You could do something with recursion here but its much better to use something like DomDocument which maintains a recursive tree for you to traverse with less code.
You can use recursion here.
Try this.
function traverse($array){
foreach($array as $item){
if(is_array($item)){
traverse($item);
}else echo $item . "<br/>";
}
}
traverse($array);
If you don't need dynamically go any deeper it would be like:
foreach($array as $mains) {
foreach($mains as $level){
var_dump($level);
}
}
If you want go deeper when $level has any children go with this:
function explore($array) {
foreach ($array as $child) {
if (gettype($child) === 'array')) {
explore($child);
} else {
echo $child;
}
}
}
// init
explore($array);
Related
My arrays
a:3:{s:6:"Choice";a:2:{i:0;s:5:"First";i:1;s:6:"Second";}s:5:"fcode";s:26:"form_rajas_exmsw2rpc81anlj";s:9:"useremail";s:26:"rajasekarang.cud#gmail.com";}
array (
'Choice' =>
array (
0 => 'First',
1 => 'Second',
),
'fcode' => 'form_rajas_exmsw2rpc81anlj',
'useremail' => 'rajasekarang.cud#gmail.com',
)
my php code
$arrays = 'a:3:{s:6:"Choice";a:2:{i:0;s:5:"First";i:1;s:6:"Second";}s:5:"fcode";s:26:"form_rajas_exmsw2rpc81anlj";s:9:"useremail";s:26:"rajasekarang.cud#gmail.com";}';
$decode = unserialize($arrays);
foreach($decode as $key => $value) {
echo '<td width="100">' . $value . '</td>';
}
My Error is :
Notice: Array to string conversion in....
The first Values in Nested Array.
How to convert nested array as a Value?
I need to show like this,
<tr><td>First,Second</td><td>form_rajas_exmsw2rpc81anlj</td><td>rajasekarang.cud#gmail.com</td></tr>
If $value is an array, you need a nested loop.
foreach ($decode as $key => $value) {
if (!is_array($value)) {
$value = array($valule);
}
foreach ($value as $subvalue) {
echo "<td width='100'>$subvalue</td>";
}
}
If you can have multiple levels of nesting, you should write a recursive function that handles each level.
If you want a sub-array to be shown as a comma-separated list, you can use implode.
foreach ($decode as $key => $value) {
if (is_array($value)) {
$value = implode(', ', $value);
}
echo "<td width='100'>$subvalue</td>";
}
you have nested array populated with elements of diferent size so you will always get an error. so in your foreach loop, you can check if the value is an array or not, like for instance
if (count($value)>1){
//code here like for instance echo $value[0]...
}//not recomended becuse an array can have only one value, but you can if you know you will put at least 2
or
if(is_array($value)..
Me I will do the following:
foreach($thing as $thingy =>$that){
//check if array or not
if(is_array($that)){
foreach($that as $t)
//do whatever
}else
//do whatever
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Loop an array of array
So I know how to traverse an array of even key => value (associative), but I have a weird array where I need to walk through it and print out values:
$object_array = array(
'type' => 'I am type',
array(
'property' => 'value',
'property_2' => 'value_2'
)
);
What I thought I could do is:
foreach($object as $key=>$vlaue){
//what now?
}
So as you can see I am lost, how do I walk through the next array?
You can try:
function traverse($array) {
foreach ($array as $key => $value) {
if (is_array($value)) {
traverse($array);
continue;
}
echo $value;
}
}
foreach($object as $key=>$value){
if( is_array($value) ) {
foreach($value as $key2=>$value2) {
//stuff happens
}
} else {
//other stuff
]
}
Try:
foreach($object_array as $value) {
if(!is_array($value))
echo $value;
else {
foreach($value as $m)
echo $m;
}
}
Manual for foreach
In your for loop you could do:
if(is_array($object[$key]))
//process inner array here
It depends on how deep your arrays go, if you have arrays of arrays of arrays...and so on, a different method would be better, but if you just have one level this is a pretty simple way of doing it.
Well, you could do something like this:
foreach($object_array as $key=>$value)
{
if(is_array($value) {
foreach($value as $k=>$v) {
echo $k." - ".$v;
}
} else {
echo $key." - ".$value;
}
}
An alternative with array_walk_recursive():
function mydebug($value, $key) {
echo $key . ' => ' . $value . PHP_EOL;
}
array_walk_recursive($object_array, 'mydebug');
Handy if you doing something simple with the values (e.g. just echo ing).
i am trying to automate my navigation links. How do I automatically echo out foreach. I am getting undefined offset right now... And can I ignore the first item in the array (i.e. title)?
'control' => array( 0=>'Controls',
1=> array('Add school','add.school.php'),
2=> array('Add doctor','add.doctor.php'),
3=> array('Add playgroup','add.play.php'),
4=> array('Suggestions','suggestion.php'),
5=> array('List tutor service','list.tutor.php'),
6=> array('Create playgroup','create.play.php'),
7=> array('Dashboard', 'dashboard.php')
),
<?php
foreach ($nav['control'] as $value=>$key){
echo''.$key[1].'';
}
?>
Numeric arrays are indexed from 0, not 1. You want [1] and [0] respectively.
// for key => value is more nature.
foreach ($nav['control'] as $key => $value){
// should skip the first.
if ($key === 0) {
continue;
}
// array is 0 base indexed.
echo''.$value[0].'';
}
foreach ($nav['control'] as $value=>$key) {
echo''.$key[0].'';
}
a nested array requires nested loop.
foreach($array as $key => $value){
if($key != 0){
foreach($value as $k => $v){
if($k == 0){ $title = $v;}
if($k == 1){ $link = $v;}
}
//put code to run for each entry here (i.e. <div> tags, echo $title and $link)
}
my personal practice when i only use two fields is to push the first into the array['id'] and the second as the value i.e.
while($row_links = sth->fetch (PDO::FETCH_ASSOC)){
$array[$row_links['title']] = $row_links['link'];
}
then you can use
<?php foreach($array as $key => $value){ ?>
<?php echo $key; ?>
<?php } ?>
function example()
{
foreach ($choices as $key => $choice) { # \__ both should run parallel
foreach ($vtitles as $keystwo => $vtitle) { # /
$options .= '<option value="'. check_plain($key) .'" title="' . $vtitle . '"' . $selected
.'>'. check_plain($choice) .'</option>';
} // end of vtitle
} // end of choice
return $options;
}
Answers to some of the below questions and what I am trying to achieve.
Array $choices is not numerically indexed.
Array $vtitle is numerically indexed.
They won't be shorter than each other as I have code which will take care of this before this code runs.
I am trying to return $options variable. The issue is that $choices[0] and $vtitle[0] should be used only once. Hope I was able to express my problem.
I do not want to go through the $vtitles array once for each value in $choices.
#hakre: thanks I have nearly solved it with your help.
I am getting an error for variable $vtitle:
InvalidArgumentException: Passed variable is not an array or object, using empty array
instead in ArrayIterator->__construct() (line 35 of /home/vishal/Dropbox/sites/chatter/sites
/all/themes/kt_vusers/template.php).
I am sure its an array this is the output using print_r
Array ( [0] => vishalkh [1] => newandold )
What might be going wrong ?
The below worked for me , thank you hakre
while
(
(list($key1, $value1) = each($array1))
&& (list($key2, $value2) = each($array2))
)
{
printf("%s => %s, %s => %s \n", $key1, $value1, $key2, $value2);
}
It does not work the way you outline with your pseudo code. However, the SPL offers a way to iterate multiple iterators at once. It's called MultipleIterator and you can attach as many iterators as you like:
$multi = new MultipleIterator();
$multi->attachIterator(new ArrayIterator($array1));
$multi->attachIterator(new ArrayIterator($array2));
foreach($multi as $value)
{
list($key1, $key2) = $multi->key();
list($value1, $value2) = $value;
}
See it in action: Demo
Edit: The first example shows a suggestion from the SPL. It has the benefit that it can deal with any kind of iterators, not only arrays. If you want to express something similar with arrays, you can achieve something similar with the classic while(list()=each()) loop, which allows more expressions than foreach.
while
(
(list($key1, $value1) = each($array1))
&& (list($key2, $value2) = each($array2))
)
{
printf("%s => %s, %s => %s \n", $key1, $value1, $key2, $value2);
}
Demo (the minimum number of elements are iterated)
See as well a related question: Multiple index variables in PHP foreach loop
you can't do it in foreach loop in general case. But you can do it like this in PHP5:
$obj1 = new ArrayObject($arr1);
$it1 = $obj1->getIterator();
$obj2 = new ArrayObject($arr2);
$it2 = $obj2->getIterator();
while( $it1->valid() && $it2->valid())
{
echo $it1->key() . "=" . $it1->current() . "\n";
$it1->next();
echo $it2->key() . "=" . $it2->current() . "\n";
$it2->next();
}
In older versions of PHP it will be like this:
while (($choice = current($choices)) && ($vtitle = current($vtitles))) {
$key_choice = key($choices);
$key_vtitle = key($vtitles);
next($choices);
next($vtitles);
}
Short Answer, no.
What you can do instead is:
foreach ($array1 as $k => $v)
performMyLogic($k, $v);
foreach ($array2 as $k => $v)
performMyLogic($k, $v);
If the keys are the same, you can do this:
foreach ($choices as $key => $choice) {
$vtitle = $vtitles[$key];
}
You may have to refigure your logic to do what you want. Any reason you can't just use 2 foreach loops? Or nest one inside the other?
EDIT: as others have pointed out, if PHP did support what you're trying to do, it wouldn't be safe at all.. so it's probably a good thing that it doesn't :)
Maybe you want this:
//get theirs keys
$keys_choices = array_keys($choices);
$keys_vtitles = array_keys($vtitles);
//the same size I guess
if (count($keys_choices) === count($keys_vtitles)) {
for ($i = 0;$i < count($keys_choices); $i++) {
//First array
$key_1 = $keys_choices[$i];
$value_1 = $choices[$keys_choices[$i]];
//second_array
$key_2 = $key_vtitles[$i];
$value_2 = $vtitles[$keys_vtitles[$i]];
//and you can operate
}
}
But this will work if size is the same. But you can change this code.
You need to use two foreach loops.
foreach ($choices as $keyChoice => $choice)
{
foreach ($vtitles as $keyVtitle => $vtitle)
{
//Code to work on values here
}
}
I have an array called $zip_in_distance
Array ([0] => Array([zip] => 12345, [distance] => 12345)).
If I am going to print the $value[zip], it is correct. But I get an empty array back. When I don't use a foreach-loop and I manually do the query, it is working. What am I doing wrong?
$shop = array();
foreach ($zip_in_distance as $key => $value) {
$q = Doctrine_Query::create()
->from('market m')
->where('m.zip = ? ', $value['zip'])
->execute();
$shop[] = $q;
}
return $shop;
My template:
foreach ($shops as $key => $list) {
echo $key . $list['id'] . '<br>';
}
I do have more than on market per zipcode. Thanks in advance!
Craphunter
Why use a foreach at all?
Try something like this:
return MarketTable::getInstance()
->whereIn('m.zip', array_map(
function($element) {return $element['zip'];},
$shop
))
->execute();