basics.php – stripslashes_deep($value) (CakePHP解析 #10)

今回はdispatcher.phpで呼び出されているstripslashes_deep関数を解析します。

この関数はPHPのmagic_quotes_gpcがonの場合でも問題なく動作させるために使用されています。

if (ini_get('magic_quotes_gpc') == 1) {
    if (!empty($_POST)) {
        $params['form'] = stripslashes_deep($_POST);
    }
} else {
    $params['form'] = $_POST;
}

ここで、magic_quotes_gpcがonの場合に、裏でどんな処理が行われるのかをおさらいしておきます。

マニュアルによると

オンの場合、全ての’ (シングルクオート), ” (ダブルクオート), (バックスラッシュ)および

NULL 文字がバックスラッシュで自動的にエスケープされます。 これは、addslashes() の機能と同じです。

つまり、「Is your name O’reilly?」は、「Is your name O’reilly?」に自動的に変換されるわけです。

この変換処理はHTTPリクエストデータ(GET, POST, そして COOKIE)に対して行われます。

そして、この変換されてしまったデータを元に戻すために使用されるのがstripslashes_deep()関数です。

この関数は「cake/basics.php」内に定義されています。

function stripslashes_deep($value) {
    if (is_array($value)) {
        $return = array_map('stripslashes_deep', $value);
        return $return;
    } else {
        $return = stripslashes($value);
        return $return ;
    }
}

引数が配列で無い場合と、配列の場合で処理が分かれています。

まずは配列で無い場合ですが、stripslashes関数で変換した値を返して終了しています。

stripslashes関数はmagic_quotes_gpcが行う変換処理の反対の変換を、つまり

「Is your name O’reilly?」であれば、「Is your name O’reilly?」に変換します。

次は配列の場合の処理を見てみます。

まずarray_mapですが、これは第一引数で指定されている関数を、第二引数の配列の各値を引数にして呼び出す関数です。

ここでポイントになるのはarray_map内でstripslashes_deep関数を、つまり自分自身を関数内で呼び出している点です。

これは再帰関数と呼ばれるものになりますが、初めはなぜ「stripslashes」でなく「stripslashes_deep」を呼び出す必要があるのか疑問でした。

ただし、よくよく考えてみると配列の中身も配列、更にその中身も配列の可能性が…と考えると「なるほど再帰関数ってこういう

使い方をするのか」と感心してしまいました。

この関数を作った人が関数名に「_deep」と付けたのもうなづけます。

再帰関数を理解するのにうってつけのお手本ではないでしょうか。