adding to an assoc array fails after the loop

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
mlecho
Forum Commoner
Posts: 53
Joined: Wed Feb 02, 2005 9:59 am

adding to an assoc array fails after the loop

Post by mlecho »

i am simply trying to dynamically add a new field to an array of nested assoc arrays. When i do the following:

Code: Select all

 
foreach($data as $d)
        {
        
            $date = $d['Event']['date'];
            $prettyDate = date('M j,Y', strtotime($date));                      
            $d['Event']['prettyDate'] = $prettyDate;    //this works and adds to the $d["Event"] assoc array
        }       
        print_r($data);  //but after the loop, $d["Event"]["prettyDate"] is not appended...why?
 
$d["Event"] is uneffected outside of the loop....however, if i do a print_r($d) in the loop, i see the expected addition of the "prettyDate" to the assoc array. Why does it not stay affected after the loop? And how can i remedy that?
Mark Baker
Forum Regular
Posts: 710
Joined: Thu Oct 30, 2008 6:24 pm

Re: adding to an assoc array fails after the loop

Post by Mark Baker »

foreach($data as &$d)
mlecho
Forum Commoner
Posts: 53
Joined: Wed Feb 02, 2005 9:59 am

Re: adding to an assoc array fails after the loop

Post by mlecho »

perfect...
so, to cap the learning curve, what is that "&" called, and where can i learn more about it....

Thanks a ton, by the way, it's perfect
Mark Baker
Forum Regular
Posts: 710
Joined: Thu Oct 30, 2008 6:24 pm

Re: adding to an assoc array fails after the loop

Post by Mark Baker »

Pass by reference. Technically, PHP passes everything be reference now, and it's more commonly seen when passing values to functions.

Although passed by reference, whenever a function argument is modified, PHP clones a copy of the argument within local scope, and it's the copy that is modified.

Code: Select all

 
function test($x,$y) {
    return (++$x * ++$y);
}
 
$A = 2;
$B = 3;
echo test($A,$B);
echo $A;
echo $B;
 
However, when you use the &, PHP doesn't clone a copy when the argument is modified, but modifies the original variable.

Code: Select all

 
function test(&$x,&$y) {
    return (++$x * ++$y);
}
 
$A = 2;
$B = 3;
echo test($A,$B);
echo $A;
echo $B;
 
Within the scope of a foreach loop,

Code: Select all

foreach($data as $d)
$d is a clone of the data element from the array, and any modification to $d is against the cloned copy that is discarded once the loop ends; but if prefixed by &, it's the actual element of the array that is modified.

Note, I forgot to mention, but you should also unset $d once the loop ends, otherwise you may get unpredictable results.

Code: Select all

 
foreach($data as $d) {
    $date = $d['Event']['date'];
    $prettyDate = date('M j,Y', strtotime($date));
    $d['Event']['prettyDate'] = $prettyDate;
}
unset($d);
 
You might think that this would unset the last element in the array, but it doesn't. Using the & with $d actually creates a new variable $d that is a pointer to the array element. Unsetting $d after the loop removes the pointer variable $d, but doesn't unset the array element that it's a pointer to.
Post Reply