Forum Moderators: coopster

Message Too Old, No Replies

Changing array values in foreach loop

         

Lupi

11:00 pm on Jan 5, 2011 (gmt 0)

10+ Year Member



Good evening!

For the code below, I am trying to add one field to every row of a two-dimensional array. However, I haven't managed to make the addition of values permanent. They are lost as soon as the foreach loop is exited. I'm sure I am overlooking a simple solution!? Thank you for your help. - Chris


foreach($result_array as $row) {
switch($row[0]) {
case 'LP': $row[] = "12"; break;
case 'LW': $row[] = "34"; break;
case 'YL': $row[] = "56"; break;
case 'MS': $row[] = "78"; break;
default: $row[] = $row[0]; break;
}
}

print_r($result_array);

Lupi

1:56 am on Jan 6, 2011 (gmt 0)

10+ Year Member



I found a solution, but I am not sure whether it's the best possible, as some websites mentioned drawbacks.


foreach($result_array as &$row)

milocold

6:56 am on Jan 6, 2011 (gmt 0)

10+ Year Member



Hi Lupi,

Hmm...how about this:


$x = array(
0 => array(
'0' => 'LP',
'1' => 3
),
1 => array(
'0' => 'LW',
'1' => 3
)
);

foreach($x as $key => $arrayVal ) {
switch( $arrayVal[0])
{
case 'LP':
$x[$key][] = 12;
break;
default:
$x[$key][] = 17;
break;
}
}

print_r($x);

Hope that helps,

M.Cold

Matthew1980

10:12 am on Jan 6, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi all,

>>foreach($result_array as &$row)

Having the ampersand in front of the variable name means that you are passing the values by reference, and in this particular case I don't think that's advisable.

As for this:-

foreach($result_array as $row) {
switch($row[0]) {
case 'LP': $row[] = "12"; break;
case 'LW': $row[] = "34"; break;
case 'YL': $row[] = "56"; break;
case 'MS': $row[] = "78"; break;
default: $row[] = $row[0]; break;
}
}

print_r($result_array);


Shouldn't you be writing the new values to the existing array, as $row is only a temporary $variable for while the loop is active, so it's no surprise to me that your having this issue.

A foreach does this: foreach($YOUR_ARRAY_NAME AS $TEMP_VAR_NAME) The key in the declaration is the use of AS, this instructs php to take the value of whatever is in the existing array, and then whilst the loop executes, puts those values into a temporary place.

Hope that makes sense. And hopefully I have understood your issue correctly :)

Cheers,
MRb

penders

11:03 am on Jan 6, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I found a solution, but I am not sure whether it's the best possible, as some websites mentioned drawbacks.

foreach($result_array as &$row)


I would have said this was OK - PHP5. In fact the first example on the foreach() PHP Manual page [uk2.php.net] does just that. However, you MUST call
unset($row)
afterwards - outside of your loop.

What drawbacks do some websites mention?

Matthew1980

11:48 am on Jan 6, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



^^^

Well, I stand corrected, just read that article and never realised that this could be achieved in this way, but having read it I now see what happens.

Cheers,
MRb

Readie

3:19 pm on Jan 6, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



foreach($result_array as &$row)


[php.net...]

As of PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated when you use & in foo(&$a);.


It's fine to use the ampersand when declaring a function

function something(&$some_var) {
$some_var = 'foo';
}

something($bar);

echo $bar;
(I think that's the syntax. I have honestly never used this)

However using it when actually making a call to a function is apparently bad and nasty :P

penders

4:20 pm on Jan 6, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



As of PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated when you use & in foo(&$a);.


Yes agree. However, just to be clear, this is different to the use of
&$row
in the code above.

rocknbil

4:37 pm on Jan 6, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



In your original example, don't you want continue instead of break? That should have worked. Continue = go to next iteration, break = break out of the loop completely.

Matthew1980

4:41 pm on Jan 6, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



>>Having the ampersand in front of the variable name means that you are passing the values by reference

>>It's fine to use the ampersand when declaring a function

This is fine:-

function MyFunction(&$variable){

}

Never tried it like this though:-

function MyFunction(Array &$variable){//<<Function only expects a certain type to be passed into it

}

I have just started to use this way when defining functions within classes that expects user data be of a certain type - all good fun :)


I think this is used as a less memory intensive way of accessing variable data, idea being is that if you have a large application you can use it as a pointer, kinda like * in C if memory calls. So that you don't need to pass the entire memory cluster into the for each, you can just do it by reference.

That's how I have always understood it to function, though I seldom use it.

Cheers,
MRb

penders

5:41 pm on Jan 6, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



rocknbil: In your original example, don't you want continue instead of break? That should have worked. Continue = go to next iteration, break = break out of the loop completely.


I think the break is for the inner switch statement, not the outer loop.

Matthew1980: function MyFunction(Array &$variable){//<<Function only expects a certain type to be passed into it


This is two things... type hinting AND pass by reference.

I think this is used as a less memory intensive way of accessing variable data, idea being is that if you have a large application you can use it as a pointer, kinda like * in C if memory calls. So that you don't need to pass the entire memory cluster into the for each, you can just do it by reference.


Not necessarily. PHP already manages (and saves) memory behind the scenes for you. When you pass a large array to a function by value, PHP does not necessarily make a fresh copy of that array in memory. References in PHP are not the same as C pointers. Generally, you should not be passing by reference in order to save memory. You should only pass by reference if you need to pass by reference (ie. you need to change the calling variable in the calling outer scope).