note 77382 deleted from control-structures.foreach by googleguy

From: Date: Wed, 14 Nov 2012 22:31:12 +0000
Subject: note 77382 deleted from control-structures.foreach by googleguy
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-191973@lists.php.net to get a copy of this message
Note Submitter: tcrosby at gmail dot com ---- 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.

« previous php.notes (#191973) next »