PHPについて質問です。


フォームから受け取った後の処理として下記のような
スクリプトを書いてみたのですが、いかにも冗長です。
これをスマートに書き直してください。

$tokyo = htmlspecialchars($_GET['tokyo']);
$oosaka = htmlspecialchars($_GET['oosaka']);
$nagoya = htmlspecialchars($_GET['nagoya']);
$hukuoka = htmlspecialchars($_GET['hukuoka']);

回答の条件
  • 1人2回まで
  • 登録:2008/03/27 23:14:24
  • 終了:2008/03/28 11:11:25

回答(3件)

id:litt No.1

litt回答回数9ベストアンサー獲得回数12008/03/27 23:54:54

ポイント23pt

こんな感じでいかがでしょう?

$cities = array('tokyo','oosaka','nagoya','hukuoka');

foreach ($cities as $city) {

eval("\$$city = ".htmlspecialchars($_GET[$city]).";");

}

id:taroemon

ご回答ありがとうございます。


ご回答いただいた物をそのまま使ってみたのですが、下記のようなエラーが出ます。

Parse error: syntax error, unexpected T_STRING in C:\xampp\(略)(9) : eval()'d code on line 1


もちろんこのエラーを回避できないのは私がいたらないせいだとは思うのですが、

リファレンス本を参照したところ、

「eval関数は負荷が大きいので、本当に必要な場合にのみ使うように」とありました。


他の方法をお待ちしています。

2008/03/28 00:55:23
id:tobeoscontinue No.2

tobeoscontinue回答回数213ベストアンサー獲得回数532008/03/28 00:51:55

ポイント35pt

近いものとしてP_BLOG Projectのソース(include/fnc_base.inc.php)の中にagainst_xss()というものがあります。

ただ使う場合はライセンスがGPLですので注意が必要です。

私はformで使う名前を配列に入れてhtmlの生成と値を受け取る場合の両方で使うようにしています。

function array_htmlspecialchars($vars) {
  $sanitized = array();
  foreach ($vars as $value) {
    $sanitized[] = is_array($value)
      ? array_htmlspecialchars($value)
      : htmlspecialchars($value);
  }
  return $sanitized;
}

受け取る値が配列になることがないなら必要ないです。

配列($vars)に対してhtmlspecialchars()を再帰的に適用して配列で返します。

function sanitize($vars, $names) {
  $sanitized = array();
  foreach ($names as $key) {
    if (isset($vars["$key"])) {
      $sanitized["$key"] = is_array($vars["$key"])
        ? array_htmlspecialchars($vars["$key"])
        : htmlspecialchars($vars["$key"]);
  }  }
  return $sanitized;
}

連想配列($vars:実態は$_GETや$_POST)の内$namesで指定される名前のものだけについてhtmlspecialchars()を適用して連想配列を返します。

$varsの内容が配列とならないなら

$sanitized["$key"] = htmlspecialchars($vars["$key"]);

だけでokです。

$_GET['tokyo']  = "<to&kyo>";
$_GET['oosaka'] = "<oo&saka>";
$_GET['nagoya'] = "<nago&ya>";
$_GET['hukuoka']= "<huku&oka city=\"\">";
$_GET['aomori'] = "<aomori>";
// テスト用に値を設定

extract(sanitize($_GET, array('tokyo','oosaka','nagoya','hukuoka')));
// 処理部分

echo "tokyo($tokyo)\n";
echo "oosaka($oosaka)\n";
echo "nagoya($nagoya)\n";
echo "hukupka($hukuoka)\n";
// 確認用に出力

sanitize($_GET, array())

$_GETについてarray()で指定される名前のものだけについてhtmlspecialchars()を適用した連想配列が返ります。array()で指定する利点は$_GETの中にあってもarray()で指定していなければ処理をしないということです。仮に攻撃で$_GETにある名前で変な値が設定されたとしても指定された名前のものしか処理しないので影響を受けません。

extract()は連想配列を変数にしますので$tokyo、$oosaka、$nagoya、$hukuokaが作成されます。

id:taroemon

ご回答ありがとうございます。

たくさん答えていただいてありがとうございます。

大変参考になりました。

2008/03/28 11:11:07
id:Lu-such No.3

Lu-such回答回数22ベストアンサー獲得回数12008/03/28 01:17:41

ポイント22pt

こんな感じでいかがでしょう?

$_GET['tokyo'] = '東京';

$_GET['oosaka'] = '大阪';

$_GET['nagoya'] = '名古屋';

$_GET['hukuoka']= '福岡';

foreach($_GET as $key => $val) {

$val=htmlspecialchars($val);

$array[$key]=$val;

}

extract($array);

echo $tokyo,$oosaka,$nagoya,$hukuoka;

id:taroemon

ご回答ありがとうございます。

参考になりました。

2008/03/28 11:10:57
  • id:tezcello
    フォームから受け取る値の全てに対してであれば、array_walk(), extract() も使えると思いますが、色々あるうちのこれらの値だけとなると...

    ただ、extract() を使うと、自覚が無いうちに変数が出来てしまうのでバグが潜み易い気がしています。
  • id:taroemon
    tezcelloさん。こんにちは。

    今回のは「フォームから受け取る値の全てに対して」です。

    やっぱりスクリプトは読むのと自分で作るのは全然違いますね。
    簡単な物からチャレンジしてるのですが、なかなか思うようにいきません。

    せっかくいただいたコメントを見直した時に、
    見落としてしまう可能性があるので、
    回答欄にご回答していただけると嬉しいです。

    ではまた。
  • id:GEN111
    1番の回答は eval を使わずに
    ${$city} = htmlspecialchars($_GET[$city]) ;
    でいけると思います。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません