note 108201 deleted from control-structures.foreach by googleguy
| From: | googleguy@php.net | Date: | Wed, 14 Nov 2012 22:16:22 +0000 |
| Subject: | note 108201 deleted from control-structures.foreach by googleguy | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-191936@lists.php.net to get a copy of this message | ||
Note Submitter: John Erck: erck0006 at junkyo dot gmail dot com
----
<?php
// LIMITATION: YOU CANNOT PASS THE $key BY REFERENCE USING PHP'S NATIVE foreach ($array as $key
=> &$value) CONTROL STRUCTURE
// SOLUTION: USE ArrayUtil::ForEachFn(Array &$array, $fn)
// ADDITIONAL BENEFIT:
// 1 - YOU DON'T HAVE TO WORRY ABOUT THE FOLLOWING WARNING:
// Reference of a $value and the last array element remain even after the foreach loop. It is
recommended to destroy it by unset().
// PHP 5 >= 5.3.0
// EXAMPLE OF LIMITATION
foreach ($array as &$key => &$value)
{
// YOUR CODE HERE
}
unset($value) // break the reference with the last element
// THE ABOVE EXAMPLE WILL OUTPUT:
// Fatal error: Key element cannot be a reference in...
// SOLUTION (FOR YOU TO COPY)
class ArrayUtil
{
public static function ForEachFn(Array &$array, $fn)
{
$newArray = array();
foreach ($array as $key => $value)
{
$fn($key, $value);
$newArray[$key] = $value;
}
$array = $newArray;
}
}
// EXAMPLE CALLBACK
$fn = function (&$key, &$value) { // NOTE THE FUNCTION'S SIGNATURE (USING & FOR
BOTH $key AND $value)
if ($key === 'key2')
{
$key = 'BY REF KEY EXAMPLE'; // THIS IS THE WHOLE POINT OF THIS POST
}
if ($value === 'value2')
{
$value = 'BY REF VALUE EXAMPLE';
}
};
// EXAMPLE USAGE
$array = array(
'key1' => 'value1',
'key2' => 'value2',
'key3' => 'value3',
);
print_r($array);
ArrayUtil::ForEachFn($array, $fn);
print_r($array);
/* THE ABOVE "EXAMPLE USAGE" OUTPUTS:
Array
(
[key1] => value1
[key2] => value2
[key3] => value3
)
Array
(
[key1] => value1
[BY REF KEY EXAMPLE] => BY REF VALUE EXAMPLE
[key3] => value3
)
*/
// ALSO NOTE THAT SYNTACTICALLY THIS CAN LOOK VERY SIMILAR TO PHP'S NATIVE FOREACH:
ArrayUtil::ForEachFn($array, function (&$key, &$value) {
// YOUR CODE HERE
});