Using foreach with Variable + Index combination - php

Following my unsolved question,
I'm trying to figure how to use foreach
How can I make this kind of code:
$m1="mbob";
$m2="mdan";
$m3="mbill";
$a = array('bob', 'dan', 'bill');
$i = 1; /* for illustrative purposes only */
foreach ($a as $v) {
echo "\$a[$i] => $v.\n";
echo $m[$i];
$i++;
}
To output this result:
$a[1] => bob.
mbob
$a[2] => dan.
mdan
$a[3] => bill.
mbill
I'm getting the error:
Undefined variable: m
But I'm trying to output the m1,m2,m3 variables, not just m.

That's something I've never done but you may try and give it a shot:
echo $('m' . $i);
That's similar to function invocations where you construct the function name dynamically through a string, but I don't know if it works with local variables as well.

Here is code that works, but I would not recommend it. I would recommend just storing your $m values in an array.
<?php
$m1="mbob";
$m2="mdan";
$m3="mbill";
$array = array('bob', 'dan', 'bill');
$i = 1;
foreach ($array as $value) {
echo "\$a[$i] => $value.\n";
echo '<br>';
echo ${"m".$i};
echo '<br>';
$i++;
}
?>

In your code, $m is not an array. There is a way to create variable variable names which appears to be what you are trying to do, but simpler is to create $m as an array:
$m =array("mbob","mdan","mbill");
$a = array('bob', 'dan', 'bill');
$i = 1; /* for illustrative purposes only */
foreach ($a as $v) {
echo "\$a[$i] => $v.\n";
echo $m[$i];
$i++;
}

Related

PHP How to echo a 3-dim array

After searching for an answer in this forum I found only related questions but under other context that would not apply to my case. Here's my problem:
I have a 3-dim array defined in a function like this:
$m_Array[h][$family][$iterator]
the values for
$family range from 6-10;
$iterator from 0-3 but has duplicates (0,1,2,3,1),
and the $m_Array results in values (25,26,30,31,33).
I am unable to echo the result using those indices to get these results once returned from the function.
NOTE: I was able to echo when I had 2-dim $m_Array[h][$iterator] but could not use it because the last value for the iterator would replace the second in the array.
Since I was able to echo the 2-dim, this is not a question on getting the return from the function or iterate over the indices.
Thanks.
Use print_r($arrayName) to print an array. You cannot echo an Array or Object
as others mentioned, you can use var_dump() or print_r(). If you need to access each item then you're going to need nested loops.
foreach($m_Array as $i => $h)
{
//echo $i, $key for h
foreach($h as $j => $family)
{
//echo $j, key for family
foreach($family as $k => $iterator)
{
echo $iterator;
}
}
}
try this:
$keys = array_keys($h);
for($i = 0; $i < count($h); $i++) {
echo $keys[$i] . "{<br>";
foreach($h[$keys[$i]] as $key => $value) {
echo $key . " : " . $value . "<br>";
}
echo "}<br>";
}
It prints all values and keys

Echo selected values from an associate array

i dont want to echo the last two values in an associative array, couldn's figure it out, please help.
foreach($_POST as $key => $value){
echo $value;
}
This echoes all the values, i want to echo all but the last 2.
Just count the loops and dont print the value in the last two loops.
$i = 0;
foreach($_POST as $key => $value) {
$i++;
if($i != count($_POST) && $i != count($_POST)-1) {
echo $value;
}
}
It should work to slice the array before you loop it.
<?php
$newArray = array_slice( $_POST, 0, count($_POST)-2);
foreach( $newArray AS $key => $value ) {
echo $value;
}
If you want to keep your $key value, then set the 4th parameter to true to "preserve keys":
http://php.net/manual/en/function.array-slice.php
Maybe this is just an exercise, but I do want to note, in addition, that relying on the exact order of your POST'd elements sounds like a bad design idea that could lead to future problems.
I'd rather do this:
$a = array('a' => 'q','s' => 'w','d' => 'e','f' => 'r');
$arr_count = count($a) - 2;
$i = 1;
foreach($a as $k => $val){
echo $k.' - '.$val.PHP_EOL;
if ($i == $arr_count) break;
$i++;
}
Another alternative solution:
<?php
$tot=count($_POST)-2;
while ($tot--) {
// you can also retrieve the key using key($_POST);
echo current($_POST);
next($_POST);
}

for loop append variable php

I have a xml file that i want to echo to the browser
echo $rule = $info->rule1
echo $rule = $info->rule2
Result:
example 1
example 2
Because the rule in the xml is dynamic i want to count how much rules there are and pass that variable behind the "rule"
$xml = simplexml_load_file('file.xml');
$xml_nested = $xml->monthlegenda;
echo "<ul>";
foreach ($xml_nested as $info):
for($i=1; $i < count($info); $i++){
$rule = $info->rule;
$rule .= $i;
echo $rule;
};
endforeach;
echo "</ul>";
As a result i expect:
example 1
example 2
but i get
12
You're probably looking for a way to get the property of an object from a string, which is done like so:
$instance->{$var.'string-part'.$otherVar};
In your case, that'd be:
echo $info->{'rule'.$i};
For more details, refer to the man pages on variable variables. Especially the section entitled " #1 Variable property" should be of interest to you...
But since you're echoing <ul> tags before and after the loop, I'm assuming you're trying to create a list, in which case, your echo statement should look like this:
echo '<li>', $info->{'rule'.$i}, '</li>';//comma's not dots!
Note that you'll never loop through the entire $info object, because of your for loop. You should either write:
for ($i=1,$j = count($info);$i<=$j;$i++)
{
echo $info->{'rule'.$i};
}
Note that I'm assigning count($info) to a variable, to avoid calling count on each iteration of the loop. You're not changing the object, so the count value will be constant anyway... or simply use foreach:
foreach($info as $property => $val)
{//val is probably still an object, so use this:
echo $info->{$property};
}
In the last case, you could omit the curlies around $property, but that's not recommended, but what you can do here, is check if the property concerned is a rule property:
foreach($info as $property => $val)
{
if (substr($property, 0, 4) === 'rule')
{//optionally strtolower(substr($property, 0, 4))
echo '<li>', $info->{$property}, '<li>';
}
}
That's the easiest way of doing what you're doing, given the information you've provided...
Try this code for "for":
for($i=1; $i < count($info); $i++)
{
$rule = $info->{'rule'.$i};
echo $rule;
}
Try this one:
$rule = $info->{rule.$i};
Check this
$xml = simplexml_load_file('file.xml');
$xml_nested = $xml->monthlegenda;
echo "<ul>";
foreach ($xml_nested as $info)
for($i=1; $i < count($info); $i++){
$rule = "";
$rule = $info->rule;
$rules = $rule.$i;
echo $rules;
}
echo "</ul>";

What's Faster/More Efficient For Grabbing First 10 Elements In Array

I need the key, value, and index of the first 10 elements of my sorted associative array.
$top10pts = array_slice($toppoints, 0, 10);
foreach ($top10pts as $key => $val) {
echo "<tr><td>".(array_search($key, array_keys($top10pts))+1)."</td><td>".htmlentities($key)."</td><td>".$val."</td></tr>";
}
or
for ($i=0; $i<10; $i++) {
$val = array_slice($toppoints, $i, 1);
echo "<tr><td>".($i+1)."</td><td>".htmlentities(key($val))."</td><td>".$val[key($val)]."</td></tr>";
}
or another method?
Being new to PHP, both methods seem stupid and superfluous.
This is the best method that came to my mind.
$top10pts = array_slice($toppoints, 0, 10);
$i = 1;
foreach ($top10pts as $key => $val)
echo "<tr><td>".($i++)."</td><td>".htmlentities($key)."</td><td>".$val."</td></tr>";
Notice that, for more than 10 items, this method works better because it has no conditions in the loop. In interpreters such as php, it's usually better to use internal functions rather than doing the things yourself.
Similar to ernie's answer but you dont need array slice at all
$index = 0;
foreach ($top10pts as $key => $val) {
echo "<tr><td>".$index++."</td><td>".htmlentities($key)."</td><td>".$val."</td></tr>";
if($index >=10) break;
}
Since you sorted already, a foreach will iterate in order, so I'd use a modification of your first, getting rid of the array_search: . . .
$index = 0;
$top10pts = array_slice($toppoints, 0, 10);
foreach ($top10pts as $key => $val) {
echo "<tr><td>".$index."</td><td>".htmlentities($key)."</td><td>".$val."</td></tr>";
$index++;
}

Sorting arrays: second last

ksort ($votes);
foreach ($votes as $total => $contestant){
$ordervotes[]= $contestant;
}
echo "<li> And the winner is: {$ordervotes[4]}</li>";
echo "<li> And the loser is: {$ordervotes[0]}</li>";
echo "<li> {$ordervotes[1]} came second last</li>";
This works fine when none of the '$total's are the same, if they are the same i get an error code. I realise I could use the 'max/min' to get the first and last elements of the array, but how do i go about finding the second last?
Thank you
Joe
Why don't you try:
echo $votes[count($votes)-2];
You also don't need to populate another array with the same values - you can keep them in $votes. You might also want to look into sorting your array by value instead of by key (which I assume you're trying to do).
If you're expecting duplicate keys, you need to remodel the way you're storing your data. Consider using a multidimensional array:
$votes = array(
array('name'=>'John','vote'=>10),
array('name'=>'James','vote'=>11),
array('name'=>'Jimmy','vote'=>13),
);
You will be able to sort this array using this function and code:
// This function will sort your array
function aasort (&$array, $key) {
$sorter=array();
$ret=array();
reset($array);
foreach ($array as $ii => $va) {
$sorter[$ii]=$va[$key];
}
asort($sorter);
foreach ($sorter as $ii => $va) {
$ret[$ii]=$array[$ii];
}
$array=$ret;
}
// Sort the array by the 'vote' key
aasort($votes,"vote");
// Echo out the name of the second-last person
echo $votes[count($votes)-2]['name'];
Use this:
function secondMax($arr) {
$max = $second = 0;
$maxKey = $secondKey = null;
foreach($arr as $key => $value) {
if($value > $max) {
$second = $max;
$secondKey = $maxKey;
$max = $value;
$maxKey = $key;
} elseif($value > $secondMax) {
$second = $value;
$secondKey = $key;
}
}
return array($secondKey, $second);
}
Usage:
$second = secondMax($votes);
You can retrieve it by using the function count:
$ordervotes[ (count($ordervotes)-2) ]
// the array starts with index 0, so (count($ordervotes)-1) is the last element
I don't understand what is in your $votes variable ... How could you have multiple contestants with the same votes (and so, with the same key).
I think there is a mistake here.
You $votes should be like this :
$votes = array(
'contestant 1' => 8,
'contestant 2' => 12,
'contestant 3' => 3
);
Then order the array : sort($votes)
Finaly, get the second last : $votes[count($votes) - 2];

Categories