Web aym.pekori.to

第 56章PHP と HTML

PHP と HTML は深く関係しています。PHP は HTML を生成し、HTML には PHP に 送信される情報が記述されています。 以下の FAQ を読む前に、どうやって PHP の外部から来る変数を取得するかを読んでおくことは重要です。 このマニュアルにはこのトピックに関するよい例があります。 register_globals の意味するところにも 注意を払ってください。

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

1. フォームから、もしくは URL から値を渡す場合にはどういった エンコード/デコードが必要なのですか?

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

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

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

例 56-1. HTML の hidden 要素

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

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

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

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

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

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

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

2. <input type="image"> タグを使おうとしているのですが、変数 $foo.x と $foo.y が使えません。どうすればよいのですか?

以下のようなタグを使えば、標準のボタンの代わりに画像を使用して フォームを送信することができます。
<input type="image" src="image.gif" name="foo" />
ユーザが画像のどこかをクリックすると、そのフォームの内容に foo.x と foo.y という 2 つの変数が追加され、サーバに送信されます。

PHP では $foo.x と $foo.y という名前は変数名として正しくないので、 自動的に $foo_x と $foo_y という名前に変換されます。要は、ピリオドが アンダースコアに置き換えられる、と言うことです。そのため、これらの 変数にアクセスする際には PHP の外部から来る変数 の取得についてのセクションで記述されているのと同様な方法を とります。たとえば $_GET['foo_x'] などです。

注意: リクエスト変数名の中のスペースは、アンダースコアに置き換えられます。

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

フォームの内容を 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[]" />
上記の 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 の外部から来る変数 も参照ください。

4. "select multiple" タグで選択された全ての結果を取得するには どうすればよいですか?

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

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

5. Javascript から PHP に変数を渡すには?

Javascript は(普通は)クライアントサイド技術であり、一方 PHP は(普通は) サーバーサイド技術です。また HTTP は"ステートレスな"プロトコルです。 そのため、この二つの言語はダイレクトに変数を共有することができません。

しかしながら、この二つの言語の間で変数を渡すことは可能です。 一つの方法は PHP と一緒に Javascript のコードを生成し、 ブラウザに自動的にリフレッシュ(再ロード)させることです。 以下の例はまさにそれで、PHP に画面の高さと幅を認識させています。 これは通常はクライアントサイドでしかできないことです。

<?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();
}
?>