开发者

function calling itself

a开发者_运维知识库gain with another problem.

public function __construct() {
    $_GET = $this->clean($_GET);
    $_POST = $this->clean($_POST);
    ...

}

public function clean($data) {
    if (is_array($data)) {
        foreach ($data as $key => $value) {
            unset($data[$key]);

            $data[$this->clean($key)] = $this->clean($value);
        }
    } else { 
        $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
    }

    return $data;
}

i dont understand why $data[$this->clean($key)] = $this->clean($value); is calling its own function. what is the point of doing this? the advantages

thanks, daniel


It's a technique called recursion. This particular function descends into the structure until it is dealing with very simple data and sanitizes it all.

Given this:

$arr = array (
   '<foo' => array(
       'bat' => 'OMGWTFBBQ!!><!?!'
   ),
   'bar' => 'baz'
);

It would start:

  1. is arr an array?
    1. is <foo an array? (no)
      • <foo becomes &lt;foo
      • &lt;foo used as a key
    2. is the value of <foo an array? (yes)
      1. Is bat an array? (no)
        • bat remains as is (still has htmlspecialchars called, but it does not change anything))
      2. Is 'OMGWTFBBQ!!><!?!' an array (no)?
        • 'OMGWTFBBQ!!><!?!' is converted to 'OMGWTFBBQ!!&gt;&lt;!?!'
        • 'OMGWTFBBQ!!&gt;&lt;!?!' is used for the value for bat.
    3. Is 'bar' an array? (no)
      1. bar returned as is (like bat above)
      2. Is baz an array? (no)
        • baz returned as is.

You can think of it this way

$arr = array (
   '<foo' => array(
       'bat' => 'OMGWTFBBQ!!><!?!'
   ),
   'bar' => 'baz'
);

///////////////////////////////////////////
array (
   clean('<foo') => array(
       'bat' => 'OMGWTFBBQ!!><!?!'
   ),
   'bar' => 'baz'
);

///////////////////////////////////////////
array (
   '&lt;foo' => clean( array(
       'bat' => 'OMGWTFBBQ!!><!?!'
   )),
   'bar' => 'baz'
);

///////////////////////////////////////////
array (
   '&lt;foo' => array(
       clean( 'bat' ) => 'OMGWTFBBQ!!><!?!'
   )),
   'bar' => 'baz'
);

///////////////////////////////////////////
array (
   '&lt;foo' => array(
       'bat' => clean( 'OMGWTFBBQ!!><!?!' )
   )),
   'bar' => 'baz'
);

///////////////////////////////////////////
array (
   '&lt;foo' => array(
       'bat' => 'OMGWTFBBQ!!&gt;&lt;!?!'
   )),
  clean( 'bar' ) => 'baz'
);
///////////////////////////////////////////
array (
   '&lt;foo' => array(
       'bat' => 'OMGWTFBBQ!!&gt;&lt;!?!'
   )),
  'bar' => clean( 'baz' )
);
///////////////////////////////////////////
return array (
   '&lt;foo' => array(
       'bat' => 'OMGWTFBBQ!!&gt;&lt;!?!'
   )),
  'bar' => 'baz'
);


clean function uses htmlspecialchars to clean html chars from string. But if $data is an array it calls itself for cleaning all of its keys and values. This is why clean is recursive.

The advantage of this approach is clean function works for string and array transparently.


It's called recursion.

In your example the $_GET and $_POST arrays may contain elements which are also arrays which themselves can contain arrays (ad infinitum). So you don't know how many sub-arrays you will have to clean up.

To solve this problem the function clean is written in a manner that it calls itself when it occurs a "sub array" while cleaning the current array. It's like a loop just for nested data structures.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜