PHP と HTML は深く関係しています。PHP は HTML を生成し、HTML には PHP に 送信される情報が記述されています。 以下の FAQ を読む前に、どうやって 外部から来る変数を取得するかを読んでおくことは重要です。 このマニュアルにはこのトピックに関するよい例があります。 register_globals の意味するところにも 注意を払ってください。
エンコードが重要になる場面はいくつかあります。 string $data という エンコードされていない文字列データを渡す場合について考えてみると、
HTML を通じて渡す場合: 文字列にはどのような値が含まれるか分からないので、 データは必ず htmlspecialchars を行い、 ダブルクオートで囲まなければなりません。
URL を通じて渡す場合: URL はいくつかのパーツから成り立ちます。 このデータをそのパーツのうちの一つであると解釈させたいならば、 urlencode() でエンコード しなければなりません。
例1 HTML の hidden 要素
<?php
echo '<input type="hidden" value="' . htmlspecialchars($data) . '" />'."\n";
?>
注意: $data を urlencode() をしては いけません。なぜなら、その作業はブラウザに任されているからです。 一般に普及している全てのブラウザは正しくこの処理を行ってくれます。 ただ、この処理はメソッド(GET や POST)が何であるかにかかわらずに 行われるということに気をつけてください。この処理に気づくのは GET リクエストのときだけになるでしょう。なぜなら POST リクエストの内容は通常目に触れることは無いからです。
例2 ユーザーによって編集するデータ
<?php
echo "<textarea name='mydata'>\n";
echo htmlspecialchars($data)."\n";
echo "</textarea>";
?>
注意: ブラウザはエスケープされたシンボルを解釈するので、data は 意図したとおりに表示されます。 フォームの内容を送信するとき、GET か POST かにかかわらず data は ブラウザによって URL エンコードされ、PHP によって URL デコードされます。 要は、URL エンコード/デコードを自分で行う必要はなく、これらの処理は すべて自動的に行われると言うことです。
例3 URL 中の場合
<?php
echo '<a href="' . htmlspecialchars("/nextpage.php?stage=23&data=" .
urlencode($data)) . '">'."\n";
?>
注意: この例では、実は GET リクエストを摸擬しています。このため、data を手動で urlencode() する必要があります。
注意: 全ての URL を htmlspecialchars() する必要があります。 なぜなら、この URL は HTML の value 属性として扱われるからです。 この場合は、ブラウザはまず htmlspecialchars() された データを元に戻し、それから URL を渡します。URL は urlencode() されているので、PHP はこれを正しく 解釈することができます。 URL 中の & が & に置き換えられていることに気づくでしょう。もしあなたがこれを忘れても ほとんどのブラウザは元に戻してくれますが、必ずそうしてくれるとは 限りませんので、URL が動的に変更されるものでなくても URL は htmlspecialchars() されるべき です。
以下のようなタグを使えば、標準のボタンの代わりに画像を使用して フォームを送信することができます。
<input type="image" src="image.gif" name="foo" />
PHP では $foo.x と $foo.y という名前は変数名として正しくないので、 自動的に $foo_x と $foo_y という名前に変換されます。要は、ピリオドが アンダースコアに置き換えられる、と言うことです。そのため、これらの 変数にアクセスする際には 外部から来る変数 の取得についてのセクションで記述されているのと同様な方法を とります。たとえば $_GET['foo_x'] などです。
注意:
リクエスト変数名の中のスペースは、アンダースコアに置き換えられます。
フォームの内容を PHP スクリプトで配列として受け取るには、 <input>、<select> あるいは <textarea> といった要素の name を以下のように指定します:
<input name="MyArray[]" /> <input name="MyArray[]" /> <input name="MyArray[]" /> <input name="MyArray[]" />
<input name="MyArray[]" /> <input name="MyArray[]" /> <input name="MyOtherArray[]" /> <input name="MyOtherArray[]" />
<input name="AnotherArray[]" /> <input name="AnotherArray[]" /> <input name="AnotherArray[email]" /> <input name="AnotherArray[phone]" />
注意:
HTML に配列のキーを指定するかどうかは自由です。キーを指定しなかった 場合はフォームに現れる順番に番号がつけられます。最初の例だと、 キーは 0、1、2、3 となります。
"select multiple" タグを使うと、ユーザーはリストから複数の項目を 選択することができるようになります。選択された項目はフォームの action で指定されたハンドラに渡されます。問題は、これらの値が全て 同じ名前で渡されることです。つまり、
<select name="var" multiple="yes">
var=option1 var=option2 var=option3
<select name="var[]" multiple="yes">
JavaScript を使っている場合、フォーム要素に要素名を使って(訳注: document.myform.myelement.value 等の様に)アクセスしようとすると、 要素名に含まれる [] が問題となることがあるので 気をつけてください。この場合は、数字で表されるフォーム要素の ID を 使用するか、シングルクオートで要素名を囲んでフォーム要素の配列の インデックスとしてアクセスしてください。例えば、以下のようにします:
variable = documents.forms[0].elements['var[]'];
Javascript は(普通は)クライアントサイド技術であり、一方 PHP は(普通は) サーバーサイド技術です。また HTTP は"ステートレスな"プロトコルです。 そのため、この二つの言語はダイレクトに変数を共有することができません。
しかしながら、この二つの言語の間で変数を渡すことは可能です。 一つの方法は PHP と一緒に Javascript のコードを生成し、 ブラウザに自動的にリフレッシュ(再ロード)させることです。 以下の例はまさにそれで、PHP に画面の高さと幅を認識させています。 これは通常はクライアントサイドでしかできないことです。
例4 PHP による Javascript の生成
<?php
if (isset($_GET['width']) AND isset($_GET['height'])) {
// ジオメトリ値を出力する
echo "画面の幅: ". $_GET['width'] ."<br />\n";
echo "画面の高さ: ". $_GET['height'] ."<br />\n";
} else {
// ジオメトリ変数を渡す
// (元のクエリ文字列を保持する
// -- POST 変数は別の方法で扱う必要がある)
echo "<script language='javascript'>\n";
echo " location.href=\"${_SERVER['SCRIPT_NAME']}?${_SERVER['QUERY_STRING']}"
. "&width=\" + screen.width + \"&height=\" + screen.height;\n";
echo "</script>\n";
exit();
}
?>