PHP のサンプルコード。 foo パラメータの値と gettype 関数で取得した型を出力する。
sample.php
<?php
function dump($key, $val) {
$valType = gettype($val);
echo("${key}: ${val} (${valType})\n");
}
dump('foo', $_GET['foo']);
簡易的に ビルトインウェブサーバー を起動して挙動を見る。
$ php -S 0.0.0.0:8888
他のターミナルから、いろんなパターンでアクセスしてみる。
普通に foo=hello と指定。
$ curl "http://localhost:8888/sample.php?foo=hello"
foo: hello (string)
foo=111&foo=222 と同じパラメータ名で値を2つ指定。後者のパラメータが有効になっている。
$ curl "http://localhost:8888/sample.php?foo=111&foo=222"
foo: 222 (string)
パラメータ名 foo だけ指定して、値は指定しない。この場合は空文字列が取得される。
$ curl "http://localhost:8888/sample.php?foo="
foo: (string)
パラメータ名 foo を指定しない。この場合は値が NULL になる (そして $_GET に存在しないキーのため Notice メッセージが出力される)。
$ curl "http://localhost:8888/sample.php?"
<br />
<b>Notice</b>: Undefined index: foo in <b>/Users/hoge/sample.php</b> on line <b>8</b><br />
foo: (NULL)
日本語「あ」を UTF-8 でエンコードした値「%E3%81%82」を指定。そのまま「あ」が取得できた。おや・・・?
$ curl "http://localhost:8888/sample.php?foo=%E3%81%82"
foo: あ (string)
あやしいので、もうちょっとサンプルコードを書いて調べてみる。
sample2.php
<?php
if ($_GET['foo'] === '%E3%81%82') {
# エンコードした値のまま
echo "encoded\n";
}
if ($_GET['foo'] === 'あ') {
# デコードされている
echo "decoded\n";
}
「decode」と表示されたので、エンコードした「%E3%81%82」は、$_GET するとデコードされているようだ。
$ curl "http://localhost:8888/sample2.php?foo=%E3%81%82"
decoded
マニュアルを漁ってみると、ちゃんと書いてあった。
警告
スーパーグローバル $_GET および $_REQUEST の内容はすでにデコード済みのものです。 $_GET や $_REQUEST の要素に対して urldecode() を使用すると、予期せぬ危険な結果となります。
PHP: urldecode - Manual
注意:
GET 変数は urldecode() 関数を介して渡されます。
PHP: $_GET - Manual
与えられた文字列中のあらゆるエンコード文字 %## をデコードします。 プラス記号 ('+') は、スペース文字にデコードします。
PHP: urldecode - Manual
今回の環境: Mac OS X El Capitan + PHP 7.0
$ uname -mrsv
Darwin 15.5.0 Darwin Kernel Version 15.5.0: Tue Apr 19 18:36:36 PDT 2016; root:xnu-3248.50.21~8/RELEASE_X86_64 x86_64
$ php -v
PHP 7.0.7 (cli) (built: May 27 2016 11:13:44) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
tags: php
Posted by NI-Lab. (@nilab)