note 77382 added to control-structures.foreach
| From: | tcrosby at gmail dot com | Date: | Mon, 27 Aug 2007 13:37:15 +0000 |
| Subject: | note 77382 added to control-structures.foreach | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-129834@lists.php.net to get a copy of this message | ||
Using the much-maligned ability of foreach to work on references rather than copies, it becomes
possible to recurse indefinitely into deep arrays without the need to know beforehand how deep they
go. Consider the following example (which I use to sanitize input):
<?php
// Sanitize as a function to allow recursing; original array passed by reference
function sanitize(&$array) {
foreach ($array as &$data) {
if (!is_array($data)) { // If it's not an array, clean it
$data = '\\' . $data; // addslashes(), mysql_real_escape_string()
or whatever you wish to use, this is merely a simple example
}
else { // If it IS an array, call the function on it
sanitize($data);
}
}
}
// Test case
$test = array(
array(
array(
0,
1,
2
),
3,
4
),
5,
6
);
// Output
sanitize($test);
print_r($test);
/*
Output:
Array
(
[0] => Array
(
[0] => Array
(
[0] => \0
[1] => \1
[2] => \2
)
[1] => \3
[2] => \4
)
[1] => \5
[2] => \6
)
*/
?>
When first called on $test, it passes a reference to the original $test array to the sanitize
function, which begins to iterate through its contents with the immediate foreach loop. Each value
that is not in itself an array gets sanitized as normal, and as both the foreach loop and the
function itself are acting by reference, all changes happen directly to the contents of the
superglobal rather than to copies. If the value given IS an array, it then calls the same function
on it. The key here is that both the function and the foreach loop work by reference, meaning that
you can call the calling function while in the foreach loop and all changes are still applied to the
original array, without corruption of the array pointer, as it remains intact for each level of the
array. When the end of an array is reached, the function simply returns; if it was a deeper-level
array, the parent function (and parent foreach loop) continue as they were; if the top-level loop
ends, then the function returns to the main code, having acted on the entire array. As everything
operates within the scope of the sanitize function, you even avoid the danger of leaving the last
reference set, as $data is not available outside the scope of the function in which any particular
loop operates. While this might sound complicated at first, the result is that by passing to
foreach by reference, true indefinite recursion is possible.
----
Server IP: 194.145.210.3
Probable Submitter: 82.153.175.147
----
Manual Page -- http://www.php.net/manual/en/control-structures.foreach.php
Edit -- https://master.php.net/note/edit/77382
Del: integrated -- https://master.php.net/note/delete/77382/integrated
Del: useless -- https://master.php.net/note/delete/77382/useless
Del: bad code -- https://master.php.net/note/delete/77382/bad+code
Del: spam -- https://master.php.net/note/delete/77382/spam
Del: non-english -- https://master.php.net/note/delete/77382/non-english
Del: in docs -- https://master.php.net/note/delete/77382/in+docs
Del: other reasons-- https://master.php.net/note/delete/77382
Reject -- https://master.php.net/note/reject/77382
Search -- https://master.php.net/manage/user-notes.php