| バイト列(16進・先頭64バイト) | 3c 62 3e e5 a4 aa e5 ad 97 3c 2f 62 3e |
バイト数 strlen() | 13 |
文字数 mb_strlen() | 9 |
UTF-8として正しいか mb_check_encoding() | 正しい |
nullバイト(00)を含むか | 含まない |
画面の入力欄に見えている文字と、サーバーに届いたバイト列は同じとは限らない。 改行・nullバイト・不正なバイト列は画面では見えにくいが、バイト列を見れば分かる。
preg_match('/^[0-9]+$/', $v) | 弾く |
preg_match('/\A[0-9]+\z/', $v) | 弾く |
$ は「末尾の改行の直前」にも一致するため、123+改行 を通してしまう。
文字列全体を検査するなら \A と \z を使う(「数字+末尾の改行」で試す)。
下の枠は、サーバーが作った HTML をブラウザがどう解釈するかを見るための表示枠 (sandbox 付き iframe)。枠の中でスクリプトが動いても、演習サイトの Cookie には触れない。
入力がそのまま HTML として解釈される。
<p>こんにちは、<b>太字</b> さん</p> <input value='<b>太字</b>' size='40'>
< > & " は変換されるが ' は変換されない。シングルクォートの属性値では足りない。
<p>こんにちは、<b>太字</b> さん</p> <input value='<b>太字</b>' size='40'>
正しい出し方。' も変換される。
<p>こんにちは、<b>太字</b> さん</p> <input value='<b>太字</b>' size='40'>
DB に入れる前にエスケープし、表示時にもエスケープした状態。< のように二重に変換され、画面に記号がそのまま出る。
<p>こんにちは、&lt;b&gt;太字&lt;/b&gt; さん</p> <input value='&lt;b&gt;太字&lt;/b&gt;' size='40'>
「UTF-8として不正なバイト列」を送ると、htmlspecialchars() は
空文字列を返す(不正な入力を黙って消す)。入力の段階で mb_check_encoding() で弾いておく理由の一つ。