[PHP-doc 19] Re: FAQ和訳(html.xml)

Masaki Fujimoto php-doc@php.gr.jp
Sat, 17 Nov 2001 23:30:23 +0900


ふじもとです。

進捗状況:

databases.xml         藤本 ドラフト
installation.xml      藤本 ドラフト
migration.xml         藤本 ドラフト
obtaining.xml         藤本 ドラフト
build.xml             廣川 作業中
general.xml           藤本 ドラフト
languages.xml         藤本 ドラフト
migration4.xml        藤本 ドラフト
using.xml             藤本 作業中
com.xml               藤本 ドラフト 
html.xml              藤本 ドラフト
mailinglist.xml       藤本 ドラフト
misc.xml              藤本 ドラフト
(敬称略)

以下、html.xmlのドラフトです。(http://www.studio-m.com/php/xml/html.xml
にも置いておきます。)

--- ここから ---
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision: 1.11 $ -->
 <chapter id="faq.html">
  <title>PHPとHTML</title>
  <titleabbrev>PHPとHTML</titleabbrev>

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

  <qandaset>
   <qandaentry id="faq.html.encoding">
    <question>
     <para>
      フォームから、もしくはURLから値を渡す場合にはどういったエンコード/デコー
      ドが必要なのですか?
     </para>
    </question>
    <answer>
     <para>
      エンコードが重要になる場面はいくつかあります。<type>string</type>
      <varname>$data</varname>というエンコードされていない文字列データを渡す場
      合について考えてみると:
      <itemizedlist>
       <listitem>
        <para>
         HTMLを通じて渡す場合: 文字列にはどのような値が含まれるか分からないので、データ
         は<emphasis>必ず</emphasis>htmlescapeを行い、ダブルクオートで囲まなけ
         ればなりません。
        </para>
       </listitem>
       <listitem>
        <para>
         URLを通じて渡す場合: URLはいくつかのパーツから成り立ちます。このデータをそのパーツの
         うちの一つであると解釈させたいならば、<function>urlencode</function>
         でエンコード<emphasis>しなければなりません。</emphasis>
        </para>
       </listitem>
      </itemizedlist>
     </para>
     <para>
      <example>
       <title>HTMLのhidden要素</title>
        <programlisting role="php">
<![CDATA[
<?php
    echo "<input type=hidden value=\"" . htmlescape($data) . "\">\n";
?>
]]>
        </programlisting>
      </example>
      <note>
       <simpara>
        <varname>$data</varname>を<function>urlencode</function>をしてはいけま
        せん。なぜなら、その作業はブラウザに任されているからです。一般に普及し
        ている全てのブラウザは正しくこの処理を行ってくれます。ただ、この処理は
        メソッド(GETやPOST)が何であるかにかかわらずに行われる、ということに気
        をつけてください。この処理に気づくのはGETリクエストのときだけになるで
        しょう。なぜならPOSTリクエストの内容は通常目に触れることは無いからです。
       </simpara>
      </note>
      <example>
       <title>ユーザによって編集するデータ</title>
        <programlisting role="php">
<![CDATA[
<?php
    echo "<textarea name=mydata>\n";
    echo htmlescape($data)."\n";
    echo "</textarea>";
?>
]]>
        </programlisting>
      </example>
      <note>
       <simpara>
        ブラウザはエスケープされたシンボルを解釈するので、dataは意図したとおり
        に表示されます。
       </simpara>
       <simpara>
        フォームの内容を送信するとき、GETかPOSTかにかかわらずdataはブラウザに
        よってURLエンコードされ、PHPによってURLデコードされます。要は、
        URLエンコード/デコードを自分で行う必要はなく、これらの処理は全て自動的
        に行われる、と言うことです。
       </simpara>
      </note>
      <example>
       <title>URL中の場合</title>
        <programlisting role="php">
<![CDATA[
<?php
    echo "<a href=\"" . htmlescape("/nexpage.php?stage=23&data=" .
        urlencode($data)) . "\">\n";
?>
]]>
        </programlisting>
      </example>
      <note>
       <simpara>
        これは実はGETリクエストの偽装です。従って、dataを手動で
        <function>urlencode</function>する必要があります。
       </simpara>
      </note>
      <note>
       <simpara>
        全てのURLを<function>htmlescape</function>する必要があります。なぜなら、
        このURLはHTMLのvalue属性として扱われるからです。この場合は、ブラウザは
        まず<function>htmlescape</function>されたデータを元に戻し、それから
        URLを渡します。URLは<function>urlencode</function>されているので、PHP
        はこれを正しく解釈することができます。
       </simpara>
       <simpara>
        URL中の<literal>&amp;</literal>が<literal>&amp;amp;</literal>に置き換
        えられていることに気づくでしょう。もしあなたがこれを忘れても、ほとんど
        のブラウザは元に戻してくれますが、必ずそうしてくれるとは限りませんので、
        URLが動的に変更されるものでなくてもURLは
        <function>htmlescape</function>される<emphasis>べき</emphasis>です。
       </simpara>
      </note>
     </para>
     <!-- TODO: a note about addgpcslashes? -->
    </answer>
   </qandaentry>

   <qandaentry id="faq.html.form-image">
    <question>
     <para>
      &lt;input type="image"&gt;タグを使おうとしているのですが、変数$foo.xと
      $foo.yが使えません。どうすればよいのですか?
     </para>
    </question>
    <answer>
     <para>
      以下のようなタグを使えば、標準のボタンの代わりに画像を使用してフォームを
      送信することができます:
      <programlisting role="html">
<![CDATA[
<input type="image" src="image.gif" name="foo">
]]>
      </programlisting>
      ユーザが画像のどこかをクリックすると、そのフォームの内容にfoo.xとfoo.yと
      いう2つの変数が追加され、サーバに送信されます。
     </para>
     <para>
      PHPでは$foo.xと$foo.yという名前は変数名として正しくないので、自動的に
      $foo_xと$foo_yという名前に変換されます。要は、ピリオドがアンダースコアに
      置き換えられる、と言うことです。
     </para>
    </answer>
   </qandaentry>

   <qandaentry id="faq.html.arrays">
    <question>
     <para>HTMLフォームで配列を使用するにはどうすればよいですか?</para>
    </question>
    <answer>
     <para>
      フォームの内容をPHPスクリプトで<link
      linkend="language.types.array">配列</link>として受け取るには、
      &lt;input&gt;, &lt;select&gt; or &lt;textarea&gt;といった要素のnameを以
      下のように指定します:
      <programlisting role="html">
<![CDATA[
<input name="MyArray[]">
<input name="MyArray[]">
<input name="MyArray[]">
<input name="MyArray[]">
]]>
      </programlisting>
      変数名の最後にあるブラケットに注意してください。これにより、フォームの内容が
      配列として扱われます。異なる要素に同じ名前をつけることで要素を配列にグルー
      プ分けすることができます。
      <programlisting role="html">
<![CDATA[
<input name="MyArray[]">
<input name="MyArray[]">
<input name="MyOtherArray[]">
<input name="MyOtherArray[]">
]]>
      </programlisting>
      上記のHTMLの場合、MyArrayとMyOtherArrayという2つの配列が生成され、PHPスクリプト
      に送信されます。また、配列に特定のキーを設定することもできます。
      <programlisting role="html">
<![CDATA[
<input name="AnotherArray[]">
<input name="AnotherArray[]">
<input name="AnotherArray[email]">
<input name="AnotherArray[phone]">
]]>
      </programlisting>
      この場合、配列AnotherArrayのキーは0, 1, emailそしてphoneとなります。
      </para>
      <para>
       <note>
        <para>
  HTMLに配列のキーを指定するかどうかは自由です。キーを指定しなかった場合はフォー
  ムに現れる順番に番号がつけられます。最初の例だと、キーは0, 1, 2, 3となります。
        </para>
       </note>
      </para>
      <para>
      <link linkend="ref.array">配列関数</link>と
      <link linkend="language.variables.external">PHPの外部から来る変数
      </link>も参照して下さい。
     </para>
    </answer>
   </qandaentry>

   <qandaentry id="faq.html.select-multiple">
    <question>
     <para>
      "select multiple"タグで選択された全ての結果を取得するにはどうすればよい
      ですか?
     </para>
    </question>
    <answer>
     <para>
      "select multiple"タグを使うと、ユーザはリストから複数の項目を選択するこ
      とができるようになります。選択された項目はフォームのactionで指定されたハ
      ンドラに渡されます。問題は、これらの値が全て同じ名前で渡されることです。
      つまり、
      <programlisting role="html">
<![CDATA[
<select name="var" multiple>
]]>
      </programlisting>
      選択されたそれぞれの項目はactionのハンドラに次のように渡されます:
      <programlisting>
var=option1
var=option2
var=option3
      </programlisting>
      それぞれの項目は前の変数<varname>$var</varname>の値を上書きしてしまいま
      す。この問題を解決するには、PHPの"フォームの値を配列にする"機能を使いま
      す。以下のようにするとよいでしょう。
      <programlisting role="html">
<![CDATA[
<select name="var[]" multiple>
]]>
      </programlisting>
      こうすればPHPに<varname>$var</varname>を配列として扱うように知らせること
      ができ、各項目のvalueの値は配列の要素としてvar[]に追加されます。最初の項
      目は<varname>$var[0]</varname>になり、次の項目は
      <varname>$var[1]</varname>...というようになります。
      <function>count</function>関数を使えば選択された項目の数を知ることができ
      ます。またもし必要なら<function>sort</function>関数を使ってソートを行う
      こともできます。
     </para>
     <para>
      JavaScriptを使っている場合、フォーム要素に要素名を使って(訳注:
      document.myform.myelement.value等の様に)アクセスしようとすると、要素名に
      含まれる<literal>[]</literal>が問題となることがあるので気をつけてください。
      この場合は、数字で表されるフォーム要素のIDを使用するか、シングルクオート
      で要素名を囲んでフォーム要素の配列のインデックスとしてアクセスして下さい。
      例えば、以下のようにします:
      <programlisting>
variable = documents.forms[0].elements['var[]'];
      </programlisting>
     </para>
    </answer>
   </qandaentry>
  </qandaset>
 </chapter>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:"../../manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->
--- ここまで ---

--
藤本 真樹

アストラザスタジオ
fujimoto@studio.co.jp