質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.34%

phpのHTMLをエスケープ処理する関数

解決済

回答 3

投稿

  • 評価
  • クリップ 2
  • VIEW 1,273

singlestroke

score 46

php にて、HTMLをエスケープ処理する関数として下記のようなものがありました。

function h($var) {
    if ( is_array($var) ) {
        return array_map( 'h', $var );
    } else {
        return htmlspecialchars( $var, ENT_QUOTES, 'UTF-8' );
    }
}

毎度、「htmlspecialchars( $var, ENT_QUOTES, 'UTF-8' )」を記述することが短縮できるということは理解できるのですが、その前の部分の

if ( is_array($var) ) {
        return array_map( 'h', $var );
    }


は何をしているのでしょうか。$varが配列だった場合には、、、???よくわかりませんので教えていただけますと幸いです。

よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+3

これはPHPのマニュアルを覗いたらわかる内容ではありますが、
is_array
array_map

結論から言うと、配列で渡されたものをすべてh関数を適用して戻す。


is_arrayで渡された変数が配列かどうか確認し、次のarray_mapに渡されています。
array_mapの仕様を確認すると、コールバック関数を"h"としています。
つまり、この質問のh関数自身ですね。

それにarray_mapの第2引数で$varの配列情報(is_arrayで配列と判断されたため)を渡しています。
これによりarray_map内部では、配列の要素は1つ1つ分解され、h関数を呼ぶようになっているわけです。

h関数を配列ではない変数を引数として呼び出されたものは、配列ではないので2つ目の処理htmlspecialchars側に処理が変わります。

したがって、配列だろうと、ただの変数だろうといずれにしてもhtmlspecialcharsを呼ぶようにする
という仕様のようですね。ちょっとは便利か。

追記 一応確認用のコードです:

<?php

function h( $var ) {
    if ( is_array( $var ) ) {
        return array_map( 'h', $var );
    } else {
        return htmlspecialchars( $var , ENT_QUOTES,  'utf-8' );
    }
}

// --- 必要データ準備
$arrayvar = array(
    "1" => "<h>配列</h>",
    "2" => "<input type='text' value='配列2'>配列2",
    "3" => "<script language='javascript'>alert('test');</script>",
    "4" => ""
);

$avar = "<b>test</b>";
// -----------------------------------------------------

// --- 確認
echo "配列:" . "\n";
var_dump( h( $arrayvar ) );

echo "変数:" . "\n";
var_dump( h( $avar ) );

echo "ただの値:" . "\n";
var_dump(h ( "<h1>test</h1>" ) );

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

+1

はい、array_map()関数を使っていますね。
$varが配列だった場合、配列内の要素を1つずつ取り出して、function h ()を実行させてから$var配列に戻して、全部終わったらそれをreturnする。
こういったことをやっています。

array_map関数は、第2引数で指定された配列の全要素に対して、第1引数に指定された関数を1個ずつ実行させるという機能があります。「コールバック関数」と、公式ドキュメントでは呼んでいますね。
http://php.net/manual/ja/function.array-map.php

return array_map( 'h', $var );


第一引数に指定する関数ですが、'h'と、一見ただの文字データに見えますが、これは関数名を表しています。

今回の場合だと、function h 関数ですね。
$varが配列だった場合、要素を1個取り出してそれを引数にしてh関数を実行させます。
そうすると、取り出した値が文字列だったら、そのままhtmlspecialcharasが実行されて値が返ってきますね。
仮に、取り出した要素がさらに配列だった場合でも、array_map()によってさらにその要素が取得されて・・・といった感じでどんどんループしていきます。

こうすることによって、f()関数はたとえ引数に文字列ではなく配列を渡した場合でも、その全ての値をHTMLエスケープすることが可能になっているということです。

配列の要素1つ1つを、foreachなどで展開させてからエスケープするのは手間ですから、大分省略できますね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/03/21 21:49

    ループしているということが分かりました。ありがとうございます。

    キャンセル

0

再帰という技法です
自分自身を呼び再度処理して貰うことです

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る