第 51 章 PHPとHTML

PHPとHTMLは深く関係しています:PHPはHTMLを生成し、HTMLにはPHPに送信 される情報が記述されています。

1. フォームから、もしくはURLから値を渡す場合にはどういったエンコー ド/デコードが必要なのですか?
2. input type="image" タグを使おうとしているのですが、変数 $foo.xと$foo.yが使えません。どうすればよいのですか?
3. HTMLフォームで配列を使用するにはどうすればよいですか?
4. "select multiple"タグで選択された全ての結果を取得するにはどうす ればよいですか?

エンコードが重要になる場面はいくつかあります。 string $data というエンコードされ ていない文字列データを渡す場合について考えてみると:

  • HTMLを通じて渡す場合: 文字列にはどのような値が含まれるか分か らないので、データは 必ず htmlspecialcharsを行い、 ダブルクオートで囲まなければなりません。

  • URLを通じて渡す場合: URLはいくつかのパーツから成り立ちます。 このデータをそのパーツのうちの一つであると解釈させたいならば、 urlencode() でエンコード しなけれ ばなりません。



例 51-1HTMLのhidden要素

 ?php
    echo " input type=hidden value=\"" . htmlspecialchars($data) .
"\" \n";
? 

注意 $data urlencode() をして はいけません。なぜなら、その作業はブラウザに任されているからで す。一般に普及している全てのブラウザは正しくこの処理を行ってく れます。ただ、この処理はメソッド(GETやPOST)が何であるかにかか わらずに行われる、ということに気をつけてください。この処理に気 づくのはGETリクエストのときだけになるでしょう。なぜならPOSTリ クエストの内容は通常目に触れることは無いからです。

例 51-2ユーザによって編集するデータ

 ?php
    echo " textarea name=mydata \n";
    echo htmlspecialchars($data)."\n";
    echo " /textarea ";
? 

注意 ブラウザはエスケープされたシンボルを解釈するので、dataは意図し たとおりに表示されます。

フォームの内容を送信するとき、GETかPOSTかにかかわらずdataはブ ラウザによってURLエンコードされ、PHPによってURLデコードされま す。要は、URLエンコード/デコードを自分で行う必要はなく、これら の処理は全て自動的に行われる、と言うことです。

例 51-3URL中の場合

 ?php
    echo " a href=\"" . htmlspecialchars("/nexpage.php?stage=23
data=" .
        urlencode($data)) . "\" \n";
? 

注意 この例では、実はGETリクエストを摸擬しています。このため、data を手動で urlencode() する必要があります。

注意 全てのURLを htmlspecialchars() する必要があります。 なぜなら、このURLはHTMLのvalue属性として扱われるからです。この 場合は、ブラウザはまず htmlspecialchars() されたデー タを元に戻し、それからURLを渡します。URLは urlencode() されているので、PHPはこれを正し く解釈することができます。

URL中の amp; に置き換えられていることに気づくでしょう。もしあなたがこれを忘 れても、ほとんどのブラウザは元に戻してくれますが、必ずそうして くれるとは限りませんので、URLが動的に変更されるものでなくても URLは htmlspecialchars() される べき です。



3. HTMLフォームで配列を使用するにはどうすればよいですか?

フォームの内容をPHPスクリプトで 配列 として受け取るには、 input , select or 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[]" 
上記のHTMLの場合、MyArrayとMyOtherArrayという2つの配列が生成され、 PHPスクリプトに送信されます。また、配列に特定のキーを設定するこ ともできます。
 input name="AnotherArray[]" 
 input name="AnotherArray[]" 
 input name="AnotherArray[email]" 
 input name="AnotherArray[phone]" 
この場合、配列AnotherArrayのキーは0, 1, emailそしてphoneとなります。

注意 HTMLに配列のキーを指定するかどうかは自由です。キーを指定しなかっ た場合はフォームに現れる順番に番号がつけられます。最初の例だと、 キーは0, 1, 2, 3となります。



配列関数 PHPの外部から来る変数 も参照して下さい。

"select multiple"タグを使うと、ユーザはリストから複数の項目を選 択することができるようになります。選択された項目はフォームの actionで指定されたハンドラに渡されます。問題は、これらの値が全て 同じ名前で渡されることです。つまり、

 select name="var" multiple 
選択されたそれぞれの項目はactionのハンドラに次のように渡されます:
var=option1
var=option2
var=option3
それぞれの項目は前の変数 $var の値を上書きして しまいます。この問題を解決するには、PHPの"フォームの値を配列にす る"機能を使います。以下のようにするとよいでしょう。
 select name="var[]" multiple 
こうすればPHPに $var を配列として扱うように知ら せることができ、各項目のvalueの値は配列の要素としてvar[]に追加さ れます。最初の項目は $var[0] になり、次の項目は $var[1] ...というようになります。
count() 関数を使えば選択された項目の数を知るこ とができます。またもし必要なら sort() 関数を使っ てソートを行うこともできます。

JavaScriptを使っている場合、フォーム要素に要素名を使って(訳注: document.myform.myelement.value等の様に)アクセスしようとすると、 要素名に含まれる [] が問題となることがあるので 気をつけてください。この場合は、数字で表されるフォーム要素のIDを 使用するか、シングルクオートで要素名を囲んでフォーム要素の配列の インデックスとしてアクセスして下さい。例えば、以下のようにします:

variable = documents.forms[0].elements['var[]'];