Foreach by reference or by value? [closed]

8

Is there any difference in performance and security between using foreach by reference or by value? I always use the first option (when needed) because I find the code less confusing to read.

Reference:

Here I change all the values of an array by the string exemplo using reference passing.

foreach ($array as $key => &$value) {
    $value = 'exemplo';
}

Value:

Here I change all the values of an array by the string exemplo using pass by value.

foreach ($array as $key => $value) {
    $array[$key]= 'exemplo';
}

Example:

Here's an example of my code (with a few lines removed to make it easier to understand) in which I do what some answers and comments say would go wrong, but I have no error:

foreach ($array as $key => &$value) {
    //Removida as linhas em que calculo alguns valores para a substr.
    $value['arq_descricao'] = substr($value['pes_texto'], $inicio, $tamanho);
}
    
asked by anonymous 13.10.2016 / 16:36

3 answers

3

Performance

I am not an expert on this subject, but I can guarantee that the performance in this case does not make so much difference to the point of just choosing one or the other because of that.

Security - Understanding the behavior of one and the other

The only security that is at risk is yours. I say this because it is necessary to understand the behavior of references in this case.

How did you respond in this question there is a small variation, compared to what is expected of a normal foreach, relative to the variable passed by reference.

In short: The last value is always referenced, which can cause you problems if you override the value of $value .

$array = [1, 2, 3];

foreach ($array as $key => &$value) {
    $value = $value . 'R$';
}

$value = null;

This would generate:

['1R$', '2R$', null]

See an example on IDEONE

So after using a foreach with reference, it is always good to call unset in the referenced variable (after the loop).

I'm not going to talk about this much here, because the linked question has a lot on it.

In this case, I'm not telling you not to do this (I've done it a few times). I'm just warning you that you should know all about it, for which "you do not know" cause you problems.

But, noting that a "new behavior" may occur in relation to the first foreach - and at the same time, this can also affect readability if you neglect to treat the reference variable properly - I could think of your second option as being the best.

$array = [1, 2, 3];

foreach ($array as $key => $value) {
    $array[$key] = $value . 'R$';
}

But you need to know if it is necessary and if it is wise to change the original value of your array . If you are sure that you will no longer use the "% original"%, then you can do this without fear of being happy: p

The disadvantage of reference with array

Remembering that you also have a drawback when using foreach with reference: You can only loop with foreach saved in variables. Arbitrary expressions can not be used with reference to some versions of PHP prior to 5.5.

Example:

// Certo:

$array = [];

foreach ([1, 2, 3, 4] as $key => $value) {
    $array[$key] = $value . 'R$';
}

// Errado: Isso vai gerar um erro caso use PHP 5.4

foreach ([1, 2, 3, 4] as $key => &$value) {
    $value = $value . 'R$';
}

See a small test

Draw your own conclusion

I do not want to give you an opinion on the subject, I want you to just understand that doing a foreach with reference and doing a reassignment with the array keys may seem like the same thing, but technically it is not. References can be villainous if they are not used wisely. Similarly, overwriting a value of foreach may not be a good idea if you want to keep the original values.

I'm showing you some points, because this "good practice" thing is actually quite personal. It's always best to know what you're doing and know how to use it on time.

    
13.10.2016 / 17:15
-1

If you really need the key ($ key) you use the second option, because sometimes I need to change the value of the variable, for example:

$ar = ['a'=>'x','b'=>'y'];
    foreach($ar as $key => $value){
        $ar[$key] = $value+'alterado';
}

Now if you do not change the value of the parent array ($ ar), nor use $ key, performance and reading are better (changes almost nothing, but they are better)

    
13.10.2016 / 16:57
-1

When you work with value you have a new instance of the array. When you work with reference, you modify the original array.

Basically, when you use the array by value you have a copy of this array valid only within the scope of foreach, for, while, and the like.

Run the example below to get an idea.

<?php

$array = ['a','b','c','d','e'];

echo "Array original";
echo "<pre>";
print_r($array);
echo "</pre>";

foreach($array as $k => $v) {
    $v = $k;
}

echo "Array após foreach por valor";
echo "<pre>";
print_r($array);
echo "</pre>";

foreach($array as $k => &$v) {
    $v = $k;
}

echo "Array após foreach por referência";
echo "<pre>";
print_r($array);
echo "</pre>";
    
13.10.2016 / 17:16