This question already has answers here:
How to modify an array's values by a foreach loop?
(2 answers)
Closed 4 months ago.
When you have a foreach loop like below, I know that you can change the current element of the array through $array[$key], but is there also a way to just change it through $value?
foreach($array as $key => $value){
}
It's probably really simple, but I'm quite new to PHP so please don't be annoyed by my question :)
To be able to directly assign values to $value, you want to reference $value by preceding it with & like this:
foreach($array as $key => &$value){
$value = 12321; //the same as $array[$key] = 12321;
}
unset($value);
After the foreach loop, you should do unset($value) because you're still able to access it after the loop.
Note: You can only pass $value by reference when the array is a variable. The following example won't work:
foreach(array(1, 2, 3) as $key => &$value){
$value = 12321; //the same as $array[$key] = 12321
}
unset($value);
The php manual on foreach loops
there's a function for that, and is builtin since early version of PHP, is called array_map
Related
This question already has answers here:
PHP get key value from array
(3 answers)
Closed 1 year ago.
How could I get only the entire first row from an array. (I use Laravel)
For example when I say:
$request-all();
I receive:
array:2 [
"email" => "james#hotmail.com"
"password" => "adms|Wh"
]
I want to receive:
email
password
If I understood your question correctly, you want something like this:
$keys = array_keys($array);
foreach ($keys as $key){
echo $key;
}
You can use the PHP array_keys() function to get all the keys out of an associative array.
$array = array("email"=>"james#hotmail.com", "password"=>"adms|Wh");
Get keys from $array array
print_r(array_keys($array));
You can also use the PHP foreach loop to find or display all the keys, like this:
Loop through $array array
foreach($array as $key => $value){
echo $key . " : " . $value . "<br>";
}
Why is an empty foreach loop can change the result.
I have the following code:
$variable = [1,2,3,4];
foreach ($variable as $key => &$value)
$value ++;
var_dump($variable);
The result I get is:
array (size=4)
0 => int 2
1 => int 3
2 => int 4
3 => &int 5
Now, when I add an empty foreach loop like this:
$variable = [1,2,3,4];
foreach ($variable as $key => &$value)
$value ++;
foreach ($variable as $key => $value);
var_dump($variable);
I get this :
array (size=4)
0 => int 2
1 => int 3
2 => int 4
3 => &int 4
can someone explain me why the last element doesn't change when I add the second empty loop, and why there is a & infront of the last element?
At the end of the first loop, $value is pointing to the same place as $variable[3] (they are pointing to the same location in memory):
$variable = [1,2,3,4];
foreach ($variable as $key => &$value)
$value ++;
Even as this loop is finished, $value is still a reference that's pointing to the same location in memory as $variable[3], so each time you store a value in $value, this also overwrites the value stored for $variable[3]:
foreach ($variable as $key => $value);
var_dump($variable);
With each evaluation of this foreach, both $value and $variable[3] are becoming equal to the value of the iterable item in $variable.
So in the 3rd iteration of the second loop, $value and $variable[3] become equal to 4 by reference, then during the 4th and final iteration of the second loop, nothing changes because you're passing the value of $variable[3] (which is still &$value) to $value (which is still &$value).
It's very confusing, but it's not even slightly idiosyncratic; it's the code executing exactly as it should.
More info here: PHP: Passing by Reference
To prevent this behavior it is sufficient to add an unset($value); statement after each loop where it is used. An alternative to the unset may be to enclose the foreach loop in a self calling closure, in order to force $value to be local, but the amount of additional characters needed to do that is bigger than just unsetting it:
(function($variable){
foreach ($variable as $key => &$value) $value++;
})($variable);
This is a name collision: the name $value introduced in the first loop exists after it and is used in the second loop. So all assignments to it are in fact assignments to the original array. What you did is easier observed in this code:
$variable = [1,2,3,4];
foreach ($variable as $key => &$value)
$value ++;
$value = 123; // <= here you alter the array!
var_dump($variable);
and you will see $variable[3] as 123.
One way to avoid this is, as others said, to unset ($value) after the loop, which should be a good practice as recommended by the manual. Another way is to use another variable in the second loop:
$variable = [1,2,3,4];
foreach ($variable as $key => &$value)
$value ++;
foreach ($variable as $key => $val);
var_dump($variable);
which does not alter your array.
The last element of the array will remian even after the foreach loop ..So its needed to use unset function outside the loop ..That is
$variable = [1,2,3,4];
foreach ($variable as $key => &$value) {
$value++;
}
unset($value);
var_dump($variable);
The link to the manual can be found here http://php.net/manual/en/control-structures.foreach.php
As phil stated in the comments:
As mentioned in the manual, you should unset() references after use.
$variable = [1,2,3,4];
foreach ($variable as $key => &$value) {
$value ++;
}
unset($value);
foreach ($variable as $key => $value);
print_r($variable);
Will return:
Array
(
[0] => 2
[1] => 3
[2] => 4
[3] => 5
)
Example
Explanation
Taken from the foreach() manual. (See the big red box)
Reference of a $value and the last array element remain even after the
foreach loop. It is recommended to destroy it by unset().
It basically means: That the referenced value &$value and the last element/item in the array, which in this case is 4 remain the same. To counter-act this issue, you'll have to unset() the value after use, otherwise it will stay in the array as its original value (if that makes sense).
You should also read this: How does PHP 'foreach' actually work?
After loop you should unset this reference using:
unset($value);
So your whole code should work like this:
$variable = [1,2,3,4];
foreach ($variable as $key => &$value) {
$value++;
}
unset($value);
var_dump($variable);
There is no point to put unset($value); inside the loop
Explanation - after loop $value is still set to the last element of array so you can use after your loop $value = 10; (before unset) and you will see that last element of array has been changed to 10. It seems that var_dump want to help us a bit in this case and shows there is reference for last element and of course when we use unset we have desired output of var_dump.
You could also look at the following script:
<?php
$array = [1, 2, 3, 4];
var_dump($array);
$x = &$array[2];
var_dump($array);
$x += 20;
unset($x);
var_dump($array);
?>
We don't use loop here and if reference is set to element of array, var_dump shows us this putting & before type of this element.
However if the above code we changed reference and set it this way $x = &$array; var_dump wouldn't show us any reference.
Also in the following code:
<?php
$x = 23;
$ref = &$x;
var_dump($x);
?>
var_dump() won't give us any hint.
Obligatory statement: References are evil!
Stepping through your code:
$variable = [1,2,3,4];
foreach ($variable as $key => &$value)
$value++;
After the loop completes; $value is a reference to $variable[3] and thus has the value of int(4).
foreach ($variable as $key => $value);
At each iteration, $variable[3] gets assigned an element of $variable[<k>] where 0 <= k < 3. At the last iteration it gets assigned to its own value which is that of the previous iteration, so it's int(4).
Unsetting $value in between the two loops resolves the situation. See also an earlier answer by me.
As a php beginner, I meet a problem with calculating the elements of array in php
$effect=array("a"=>array(1,2),"b"=>array(1,2),"c"=>array(1,2));
I just want to make the result as this
$effect['a'][0]=$effect['a'][0]/$effect['a'][1];
$effect['b'][0]=$effect['b'][0]/$effect['b'][1];
$effect['c'][0]=$effect['c'][0]/$effect['c'][1];
Except do this one by one , How to do this calculation with foreach or other loop way
Your array syntax is a bit off. It should be $effect['a'][0].
The loop is trivial, and foreach was the right idea.
You can use it to iterate over all the letters using:
foreach ($effect as $letter => $numbers) {
...
}
Then put your assignment/division line in the loop, replacing the fixed 'a' and 'b' etc. with the $letter variable.
You need something like this?
foreach ($effect as $key => $val)
{
$results[$key] = $val[0] / $val[1];
}
print_r($results);
Also one counter-intuitive thing in PHP, is that arrays are passed by value by default. You can use & to get a reference to the array
$effects =array("a"=>array(1,2),"b"=>array(1,2),"c"=>array(1,2));
foreach ( $effects as $key => &$effect ) {
$effect[0] = $effect[0]/$effect[1];
unset($effect);
}
print_r( $effects );
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
foreach with three variables add
i have following code i want to use multiple array in foreach. please note that i need $yourSiteContent[] as it is.
foreach ($pieces as $id and $pieces1 as $id_date) {
$yourSiteContent[] = array('permalink' => $id, 'updated' => $id_date);
}
as you can see i have two arrays ($pieces and $pieces1), please check a loop and let me know where i am doing mistake.
$pieces1 contains dates and $pieces contains urls.
thanks for your help.
Assuming both $pieces and $pieces1 have the same keys you can do the following:
for (array_keys($pieces) as $key) {
$yourSiteContent[] =
array('permalink' => $pieces[$key], 'updated' => $pieces2[$key]);
}
You should use a for loop and an indexer, then access each array.
To keep to the foreach format you can also do it like (Assuming both $pieces and $pieces1 have the same keys):
$yourSiteContent = array();
foreach ($pieces as $key=>$value) {
$yourSiteContent[] = array('permalink'=>$value,
'updated'=>$pieces1[$key]);
}
You can use array_combine() to combine the two arrays into a single array, with one being used for keys and the other for values.
foreach (array_combine($pieces, $pieces1) as $id => $id_date) {
$yourSiteContent[] = array('permalink' => $id, 'updated' => $id_date);
}
See array_combine() for more information.
I am looking for a Perl equivalent to the following php code:-
foreach($array as $key => $value){
...
}
I know I can do a foreach loop like so:-
foreach my $array_value (#array){
..
}
Which will enable me to do things with the array values - but I would like to use the keys as well.
I know there is a Perl hash which allows you to set up key-value pairs, but I just want the index number that the array automatically gives you.
If you're using Perl 5.12.0 or above you can use each on arrays:
my #array = 100 .. 103;
while (my ($key, $value) = each #array) {
print "$key\t$value\n";
}
Output:
0 100
1 101
2 102
3 103
perldoc each
Try:
my #array=(4,5,2,1);
foreach $key (keys #array) {
print $key." -> ".$array[$key]."\n";
}
Works for Hashes and Arrays.
In case of Arrays the $key holds the index.
I guess the closest Perl is something like this:
foreach my $key (0 .. $#array) {
my $value = $array[$key];
# Now $key and $value contains the same as they would in the PHP example
}
Since Perl 5.12.0, you can use the keys function on arrays as well as hashes. That might be a little more readable.
use 5.012;
foreach my $key (keys #array) {
my $value = $array[$key];
# Now $key and $value contains the same as they would in the PHP example
}