CGIモジュール v2.70

by Hippo2000(2000/8/15)

CGIモジュールは、名前のとおりCGIのためのモジュールなのです。元ネタがかなり巨大な上に2.52から2.70へのバージョンアップにも対応したので、訳がボケているかもしれませんが(そりゃいつもか)

原本の著作権はLincoln D. Stein.氏がお持ちです。詳しくは著作権情報をご覧ください。

内容等が間違っていたら修正します。ご連絡ください。

=変更履歴=

 


目次


名前

CGI - 簡単なCGI(Common Gateway Interface)クラス


概要

  # フォームを作成し、その値をエコーバックする
  # CGIスクリプト
  use CGI qw/:standard/;
  print header,
        start_html('A Simple Example'),
        h1('A Simple Example'),
        start_form,
        "What's your name? ",textfield('name'),p,
        "What's the combination?", p,
        checkbox_group(-name=>'words',
                       -values=>['eenie','meenie','minie','moe'],
                       -defaults=>['eenie','minie']), p,
        "What's your favorite color? ",
        popup_menu(-name=>'color',
                   -values=>['red','green','blue','chartreuse']),p,
        submit,
        end_form,
        hr;
   if (param()) {
       print "Your name is",em(param('name')),p,
             "The keywords are: ",em(join(", ",param('words'))),p,
             "Your favorite color is ",em(param('color')),
             hr;
   }

要約

このperlライブラリは簡単にWebのフォームを作成し、その内容を解析するためにperl5オブジェクトを使っています。このパッケージはCGIオブジェクト、現在の問い合わせ文字列の値が入ったエンティティ、そしてその他の状態変数を定義します。CGIオブジェクトのメソッドを使って、スクリプトに渡されたキーワードやパラメータの値をチェックしたり、現在の取り合わせから取得した値で初期化したフォームを作成する(これによって状態情報を保存します)ことが出来ます。このモジュールはHTMLを生成し、入力とコーディング・エラーを減らす短い名前の関数を提供します。またファイルのアップロード、カスケーディング・スタイル・シート、サーバ・プッシュ、フレームを含めたCGIスクリプトのいくつかのさらに進んだ機能も提供します。

CGI.pmはオブジェクト指向の機能を必要としない人たちのために、簡単な関数指向プログラミング・スタイルも提供します。

CGI.pmの現在のバージョンは以下のサイトから利用できます:

  http://www.genome.wi.mit.edu/ftp/pub/software/WWW/cgi_docs.html
  ftp://ftp-genome.wi.mit.edu/pub/software/WWW/

説明


プログラミング・スタイル

CGI.pmでは2つのプログラミング・スタイル、オブジェクト指向スタイルと関数指向スタイルがあります。オブジェクト指向スタイルでは、1つまたは複数のCGIオブジェクトを作成し、ページのさまなざな要素を作成するためにオブジェクト・メソッドを使います。各オブジェクトはサーバーによってスクリプトに渡された名前付きパラメータのリストが出発点となります。オブジェクトを変更したり、ファイルやデータベースに格納し、それを元に戻すことが出来ます。というのも各オブジェクトはCGIスクリプトの"状態"(state)に対応しており、各オブジェクトのパラメータ・リストはその他のものとは独立しているため、スクリプトの状態を保存し、後から取り出すこともできるのです。

以下にオブジェクト指向スタイルを使って、簡単な"Hello World"HTMLページをどのように作成するかの例を示します:

   #!/usr/local/bin/perl
   use CGI;                             # CGIルーチンのロード
   $q = new CGI;                        # 新しいCGIオブジェクトの作成
   print $q->header,                    # HTTPヘッダの作成
         $q->start_html('hello world'), # HTMLの開始
         $q->h1('hello world'),         # レベル1のヘッダ
         $q->end_html;                  # HTMLの終わり

関数指向スタイルでは、直接扱うことはまずない、1つのデフォルトのCGIオブジェクトがあります。CGIパラメータを取り出し、HTMLタグを作成し、クッキーを管理する等々のために、代りに関数を単に呼び出します。これは、よりすっきりしたプログラミング・インタフェースを提供しますが、一度には1つのCGIオブジェクトを使うように制限します。以下の例は同じページで関数指向インターフェースを使っています。大きな違いは今度は名前空間に関数のセット(通常は"standard"の関数群)をインポートする必要があること、そしてCGIオブジェクトを作成する必要がないことです。

   #!/usr/local/bin/perl
   use CGI qw/:standard/;           # 標準(standard)のCGIルーチンをロードする
   print header,                    # HTTPヘッダの作成
         start_html('hello world'), # HTMLの開始
         h1('hello world'),         # レベル1のヘッダ
         end_html;                  # HTMLの終わり

このドキュメントの例では主にオブジェクト指向スタイルを使います。CGI.pmでの関数指向プログラミングについての重要な情報は「関数のインポート方法」をご覧下さい。


CGI.PMルーチンの呼び出し

ほとんどのCGI.pmルーチンはさまざまな引数を受け取ります。なかには20ものオプションの引数を受取るものもあります!このインターフェースを簡単にするため、すべてのルーチンは以下のような名前付き引数呼び出しスタイルを使います:

   print $q->header(-type=>'image/gif',-expires=>'+3d');

各引数の名前の前にはダッシュがつきます。引数リストでは大文字/小文字や、順番は問題になりません。-type、-Type、-TYPEのすべてが受取られます。実際には、最初の引数だけがダッシュから始まる必要があります。最初の引数にダッシュがあれば、CGI.pmは後のものにもダッシュを想定します。

さまざまなルーチンは一般に1つの引数だけで呼ばれます。それらのルーチンの場合、引数名なしに1つの引数を与えることが出来ます。header()はそうしたルーチンの1つです。この場合、1つの引数はドキュメント・タイプです。

   print $q->header('text/html');

他のそのようなルーチンは下記で記述しています。

名前付き引数はあるときはスカラを期待し、あるときは配列へのリファレンス、あるいはハッシュへのリファレンスを期待します。多くの場合、どんな種類の引数も渡すことができ、ルーチンは最も適したことを行います。例えばparam()ルーチンはCGIパラメータに1つあるいは複数の値を設定するために使われます。2つの場合を以下に示します:

   $q->param(-name=>'veggie',-value=>'tomato');
   $q->param(-name=>'veggie',-value=>['tomato','tomahto','potato','potahto']);

CGI.pmのルーチンの多くがモジュール内で特に定義されておらず、必要に応じて自動的に生成されます。これらは動的に生成されるページで使われ、HTMLを生成する"HTMLショートカット"ルーチンです。HTMLタグは属性(タグ自身に入っている属性="値"の組)と内容(開始と終了の組の間の部分)の両方を持ちます。属性と内容とを区別するため、CGI.pmはHTML属性をハッシュ・リファレンスで最初の引数として、そして内容があればその後の引数として、渡すような約束を使っています。それは以下のように機能します:

   コード                          作成されるHTML
   ----                           --------------
   h1()                           <H1>
   h1('some','contents');         <H1>some contents</H1>
   h1({-align=>left});            <H1 ALIGN="LEFT">
   h1({-align=>left},'contents'); <H1 ALIGN="LEFT">contents</H1>

HTMLタグについては後で詳しく記述します。

CGIを使い始めたばかりの人の多くが、HTMLタグ属性を囲む曲括弧を必要とするHTMLショートカットの呼び出し方と、曲括弧無しに属性の生成を管理する他のルーチンの呼び出し方との違いに惑わされます。混乱しないで下さい。便宜上、曲括弧はHTMLを除くすべてでオプションです。もし好きであれば、名前付き引数を取るルーチンを呼び出すすべてのときに曲括弧を使うことが出来ます。例えば:

   print $q->header( {-type=>'image/gif',-expires=>'+3d'} );

-w スイッチを使うと、いくつかのCGI.pm引数はPerl組込関数と名前がぶつかっていることを警告されるでしょう。これらのほとんどは、複数の値を持つメニュー(multi-valued menu)、ラジオボタン(radio button)、クラスター(cluster)などを作成するために使われる-values引数です。この警告を回避するためには、たくさんの選択肢があります:

  1. もし他の名前が使えれば、引数に他の名前を使う。例えば-valueは-valuesのための別名です。
  2. 先頭を大文字化する。例. -Values
  3. 引数名の周りをクォートで囲む。 例. '-values'

多くのルーチンが理解できない名前付き引数についてもなんらか有効なことをします。例えば、名前付きの引数として与えることにより標準ではないHTTPヘッダ・フィールドを作成することが出来ます:

  print $q->header(-type  =>  'text/html',
                   -cost  =>  'Three smackers',
                   -annoyance_level => 'high',
                   -complaints_to   => 'bit bucket');

これは以下の標準ではないHTTPヘッダを作成します:

   HTTP/1.0 200 OK
   Cost: Three smackers
   Annoyance-level: high
   Complaints-to: bit bucket
   Content-type: text/html

アンダースコアが自動的にハイフンに変換される方法について注意してください。HTML作成ルーチンは異なる変換をします。

この機能はHTTPとHTMLの"標準"にすばやくついていくことを可能にします。


新しい問い合わせオブジェクトの作成(オブジェクト指向スタイル):

     $query = new CGI;

これは(POSTとGETメソッドの両方からの)入力を解析し、$queryと呼ばれるperl5オブジェクトに格納します。


入力ファイルからの新しい問い合わせの作成

     $query = new CGI(INPUTFILE);

もしファイル・ハンドルをnew()メソッドに与えると、ファイル(またはSTDINでもなんでも)からパラメータを読み込みます。デバッグ中、ファイルには以下に説明する形式ならば、何にでもすることができます(つまり改行で区切られたタグ=値の組が機能します)。便利なことに、このファイルのタイプはsave()メソッドにより作成されます。複数のレコードを保存し、元に戻すことが出来ます。

Perl純粋主義者はこの文法がファイル・ハンドルを、ファイルハンドル・グロブさえも受取ることを知って喜ぶでしょう、これはファイルハンドルを渡す"公式の"方法です:

    $query = new CGI(\*STDIN);

CGIオブジェクトをFileHandleまたはIO::Fileオブジェクトで初期化することも出来ます。

関数指向インターフェースを使っていて、CGI状態をファイル・ハンドルで初期化したければ、restore_parameters()でおこないます。これはデフォルトのCGIオブジェクトを指定されたファイル・ハンドルで(再)初期化します。

    open (IN,"test.in") || die;
    restore_parameters(IN);
    close IN;

連想配列リファレンスから問い合わせオブジェクトを初期化することも出来ます:

    $query = new CGI( {'dinosaur'=>'barney',
                       'song'=>'I love you',
                       'friends'=>[qw/Jessica George Nancy/]}
                    );

または適切にフォーマットされた、URLエスケープされた問い合わせ文字列から:

    $query = new CGI('dinosaur=barney&color=purple');

または既に存在しているCGIオブジェクトから(現在、これはパラメータ・リストの複製を作りますが、autoescapingのようなオブジェクト特有のフィールドは複写しません):

    $old_query = new CGI;
    $new_query = new CGI($old_query);

空の問い合わせを作成するためには、空文字列または空のハッシュで初期化します:

   $empty_query = new CGI("");
       -または-
   $empty_query = new CGI({});

問い合わせからのキーワードのリストの取り出し:

     @keywords = $query->keywords

<ISINDEX>検索の結果としてスクリプトが呼び出されれば、解析されたキーワードはkeywords()メソッドを使って配列として取得することが出来ます。


スクリプトの渡された全てのパラメータの名前の取り出し:

     @names = $query->param

パラメータ付きでスクリプトが呼び出されれば(例えば、"name1=value1&name2=value2&name3=value3")、param()メソッドはパラメータ名をリストで返します。もしスクリプトが<ISINDEX>スクリプトとして呼び出され、アンパサンドのない文字列が入っていれば(例えば、"value1+value2+value3")、"+"で区切られたキーワードが入った"keywords"という名前の1つのパラメータになります。

注意:バージョン1.5では、パラメータ名の配列はブラウザにより実行されたのと同じ順番でした。通常、この順序はパラメータがフォームで定義された順と同じです(しかしながら仕様には入っていないので、保証はされません。)


1つの名前つきパラメータの値を取り出す:

    @values = $query->param('foo');
              -または-
    $value = $query->param('foo');

名前付きパラメータの値を取り出すためにparam()メソッドに1つの引数を渡してください。もしそのパラメータが複数の値を持っていれば(例えばスクローリング・リスト(scrolling list)での複数の選択から)、配列で受取るようにすることが出来ます。そうでなければ、このメソッドは1つの値を返します。

もし値が問い合わせ文字列で与えられなければ、つまり問い合わせで"name1=&name2=""または"name1&name2"であれば、空文字列を返します。これは2.63での新機能です。


名前つきパラメータへの値の設定:

    $query->param('foo','an','array','of','values');

これは名前付きパラメータ'foo'の値として値の配列を設定します。これは、スクリプトが前に一度呼び出された後にフィールドの値を変更するための1つの方法です。(もう1つの方法はフォーム要素を作成するすべてのメソッドで受取られる -overrideパラメータを使うことです)

param()は下記でさらに詳しく記述する呼び出しの名前付きパラメータ形式も理解します:

    $query->param(-name=>'foo',-values=>['an','array','of','values']);
                              -または-
    $query->param(-name=>'foo',-value=>'the value');

名前つきパラメータに値を追加する:

   $query->append(-name=>'foo',-values=>['yet','more','values']);

これは値または値のリストを名前付きパラメータに追加します。既にあれば、その値はパラメータの最後に追加されます。そうでなければパラメータが作成されます。このメソッドは名前付き引数呼び出し書式しか理解しないことに注意してください。


すべてのパラメータの名前空間へのインポート:

   $query->import_names('R');

これは一連の変数を'R'名前空間に作成します。例えば$R::foo、@R:fooのように。キーワード・リストでは、変数@R:keywordがあります。名前空間が指定されなければ、この引数は'Q'を想定します。警告:何も'main'にインポートしないこと、これはセキュリティ上、大きな危険性があります!!!

古いバージョンでは、このメソッドは import()と呼ばれていました。バージョン2.20では、組込Perlモジュールimport演算子とぶつかることを避けるため、この名前は完全に削除されました。


パラメータを完全に削除する:

    $query->delete('foo');

これは完全にパラメータをクリアします。それはスクリプト呼び出しの間で、渡されたものが欲しくないパラメータをリセットするのに、ときどき便利です。

関数呼び出しインターフェースを使っているのであれば、Perlの組込みdelete演算子との衝突を避けるため、代りに"Delete()"を使ってください。


すべてのパラメータを削除する:

   $query->delete_all();

これはCGIオブジェクトを完全にクリアします。これはフォームを作成するときに、すべてのデフォルトが取られることを保証するために便利です。

関数呼び出しインターフェースを使っているならば、代りにDelete_all()を使ってください。


パラメータリストへの直接アクセス:

   $q->param_fetch('address')->[1] = '1313 Mockingbird Lane';
   unshift @{$q->param_fetch(-name=>'address')},'George Munster';

パラメータ・リストへアクセスする必要があれば、これまでのメソッドではカバーされていません。その名前でparam_fetch()を呼び出すことにより、それへの直接のリファレンスを取得することが出来ます。これは名前付きパラメータへの配列リファレンスを返します。それは好きなように扱うことが出来ます。

-nameを使って、名前付き引数スタイルを使うことも出来ます。


パラメータリストのハッシュでの取り出し:

    $params = $q->Vars;
    print $params->{'address'};
    @foo = split("\0",$params->{'foo'});
    %params = $q->Vars;
    use CGI ':cgi-lib';
    $params = Vars;

多くの人がすべてのパラメータリストを、CGIパラメータの名前をキーとし、そのパラメータの値を値とするハッシュとして取り出しがります。Vars()メソッドはこれはします。スカラコンテキストで呼ばれると、タイされたハッシュ・リファレンスとしてパラメータリストを返します。キーを変更すると、元になっているCGIパラメータリストでのパラメータの値を変更します。配列コンテキストで呼ばれると、それは通常のハッシュとしてパラメータリストを返します。これによりパラメータリストの内容を読むことが出来ますが、変更することはできません。

これを使うとき、複数の値を持つCGIパラメータについて気をつけなければいけません。ハッシュはスカラと配列のコンテキストを区別しないので、複数の値をもつパラメータは"\0"(null)文字で区切られた、パックされた文字列で返されます。個々の値を取り出すためにはパックされた文字列を分割しなければなりません。このやり方はPerlバージョン4のためのcgi-lib.plモジュールで、Steve Brrennerによって導入されました。

Vars()を関数として使いたければ、関数呼び出しセット :cgi-lib をインポートしてください。(CGI-LIBとの互換性についてのセクションもご覧下さい)


スクリプトの状態をファイルに保存する:

    $query->save(FILEHANDLE)

これはフォームの現在の状態を指定されたファイルハンドルに書き込みます。new()メソッドにファイルハンドルを与えることにより読み戻すことが出来ます。ファイルハンドルは、ファイル、パイプ、その他何にでもにすることが出来ることに注意してください!

保存されるファイルの形式は以下の通りです:

        NAME1=VALUE1
        NAME1=VALUE1'
        NAME2=VALUE2
        NAME3=VALUE3
        =

名前と値の両方がURLエスケープされます。複数の値を持つCGIパラメータは名前を繰り返すことにより表すことができます。セッション・レコードはsingle=symbolによって範囲を決められます。何回もnewを呼ぶことにより、複数のレコードを書き出し、読み戻すことが出来ます。追記(append)モードでファイルを開くことにより、複数のセッションにまたがってこれを行うことが出来ます、これにより原始的なゲスト・ブックやユーザの質問の履歴を作成することが出来ます。以下は複数のセッション・レコードを作成する短い例です:

   use CGI;
   open (OUT,">>test.out") || die;
   $records = 5;
   foreach (0..$records) {
       my $q = new CGI;
       $q->param(-name=>'counter',-value=>$_);
       $q->save(OUT);
   }
   close OUT;
   # 読み込むために再オープン
   open (IN,"test.out") || die;
   while (!eof(IN)) {
       my $q = new CGI(IN);
       print $q->param('counter'),"\n";
   }

保存/復帰に使われるファイル・フォーマットはWhitehead Genome Centerのデータ交換フォーマット"Boulderio"に使われているものと同じで、Boulderioユーティリティを使って扱ったり、さらにはデータベース化することができます。さらなる詳細は

  http://stein.cshl.org/boulder/

をご覧下さい。

関数指向(非OO)からこの関数を使いたいのであれば、このメソッドのエクスポートされた名前はsave_parameters()です。


CGIエラーの取り出し

ユーザ入力を処理して切る間、特にアップロードされたファイルを処理している間にエラーが発生することがあります。これらのエラーが発生したとき、CGIは処理を止め、空のパラメータリストを返します。エラーの存在とその性質をcgi_error() 関数を使って調べることが出来ます。エラーメッセージはHTTPステータスコードのようにフォーマットされます。HTMLページにそのエラー・テキストを入れたり、HTTPステータスの値として使うことができます。

    my $error = $q->cgi_error;
    if ($error) {
        print $q->header(-status=>$error),
              $q->start_html('Problems'),
              $q->h2('Request not processed'),
              $q->strong($error);
        exit 0;
    }

関数指向インターフェース(次のセクションをご覧下さい)を使うとき、エラーは最初にparam() を呼んだときにだけ発生します。これに備えてください!


関数指向インターフェースの使い方

関数指向インタフェースを使うためには、どの CGI.pmルーチンまたは関数群をスクリプトの名前空間にインポートするかを指定しなければいけません。このインポートに関連して少しオーバーヘッドがありますが、大したことはありません。

   use CGI <メソッドのリスト>;

リストに入れられたメソッドは現在のパッケージにインポートされます;CGIオブジェクトを最初に作成することなく、直接呼び出すことが出来ます。この例ではどのようにparam()header()メソッドをインポートし、それらを直接使うかを示しています:

   use CGI 'param','header';
   print header('text/plain');
   $zipcode = param('zipcode');

さらに多くの場合、名前でグループを参照することにより一般的な関数の組をインポートします。すべての関数の組の前には":html3"(HTML3標準で定義されたタグ用)のように、前に":"がつきます。

以下にインポートできる関数の組のリストを示します:

:cgi
param(), path_info() など、CGIを扱うすべてのメソッドをインポートします。
:form
textfield()など、フォームを作成するメソッドをインポートします。
:html2
HTML 2.0 標準要素を作成するすべてのメソッドをインポートします。
:html3
HTML 3.0 標準要素を作成するすべてのメソッドをインポートします。(<table>、<super> そして<sub>など)
:netscape
Netscape特有のHTML拡張を作成するすべてのメソッドをインポートします。
:html
すべてのHTML作成ショートカットをインポートします(つまり'html2' + 'html3' + 'netscape')...
:standard
"標準"の機能をインポートします。, 'html2', 'html3', 'form' そして 'cgi'。
:all
利用可能なすべてのメソッドをインポートします。全体のリストはCGI.pmのコードをご覧下さい。%EXPORT_TAGSという変数が定義されています。

CGI.pmの一部ではない関数名をインポートすると、モジュールはそれを新しいHTMLタグとして扱い、適切なサブルーチンを作成します。そこで他のHTMLタグと同じように使うことが出来ます。これは急速に発展するHTMLの"標準"を提供するためです。例えばMicrosoftは<GRADIENT>という新しいタグを発表しています(これはマシンをリブートするまで、ユーザのデスクトップを回転する斜線でいっぱいにします)。新しいバージョンのCGI.pmを待つ必要はありません、それをすぐに使ってみてください:

   use CGI qw/:standard :html3 gradient/;
   print gradient({-start=>'red',-end=>'blue'});

実行スピードの点から、CGI.pmはロード・シンボルを指定するための標準のExporterの書式を使わないことに注意してください。これは将来変更されるかもしれません。

もし状態管理CGI、またはフォーム作成メソッドのいずれかをインポートすると、あることを要求するメソッドのいずれかを最初に使ったときに、デフォルトのCGIオブジェクトが自動的に作成され、初期化されます。これにはparam(), textfield(), submit() などが入ります(直接CGIオブジェクトにアクセスする必要があれば、グローバル変数$CGI::Qがあります)。CGI.pmメソッドをインポートすることによって、以下のようにエレガントなスクリプトを書くことが出来ます:

   use CGI qw/:standard/;
   print 
       header,
       start_html('Simple Script'),
       h1('Simple Script'),
       start_form,
       "What's your name? ",textfield('name'),p,
       "What's the combination?",
       checkbox_group(-name=>'words',
                      -values=>['eenie','meenie','minie','moe'],
                      -defaults=>['eenie','moe']),p,
       "What's your favorite color?",
       popup_menu(-name=>'color',
                  -values=>['red','green','blue','chartreuse']),p,
       submit,
       end_form,
       hr,"\n";
    if (param) {
       print 
           "Your name is ",em(param('name')),p,
           "The keywords are: ",em(join(", ",param('words'))),p,
           "Your favorite color is ",em(param('color')),".\n";
    }
    print end_html;

プラグマ

関数セットに加えて、多くのプラグマをインポートすることができます。プラグマの前には常にハイフンがつき、CGI.pm関数の動きを多くの方法で変更します。プラグマ、関数セットそして個々の関数はすべて同じuse()行でインポートすることができます。例えば、以下のuseステートメントは標準の関数セットをインポートし、デバッグ・モードを不可能にします(プラグマ -no_debug):

   use CGI qw/:standard -debug/;

プラグマの現在の一覧を以下に示します:

-any
use CGI -anyを使うとき、問い合わせオブジェクトが理解しないすべてのメソッドはHTMLタグとして解釈されます。これにより次のNetscapeとMicrosoft特有のHTML拡張をサポートすることが出来ます。これは新しく、まだサポートされていないタグを自由に使わせてくれます:
   use CGI qw(-any);
   $q=new CGI;
   print $q->gradient({speed=>'fast',start=>'red',end=>'blue'});

anyを使うとタイプを間違えたメソッド名がHTMLタグとして解釈されるので、使うときには注意するか、まったく使わないかのどちらかにしてください。

-compile
これは指定されたオートロードされるメソッドが後に延期されるのではなく、先にコンパイルされます。これはFastCGIやmod_perlなどのMalcom BeattieのPerlコンパイラにバリバリ食わせるようになっているような状況の下で、長時間、実行されるスクリプトには有効です。使おうとしているメソッドあるいはメソッド・ファミリと結合して使ってください。
   use CGI qw(-compile :standard :html3);

または以下のようにさえも

   use CGI qw(-compile :all);

このようにして-compile プラグマを使うことは、常にコンパイルされた関数が現在の名前空間にインポートされる効果を持つことに注意してください。インポートすることなしにコンパイルしたければ、代りにcompile()メソッドを使ってください。(下記をご覧下さい)

-nosticky
これはCGI.pmにヒドゥン・フィールドを作らせません。 GETメソッドでの問い合わせ文字列でヒッドゥン・フィールドを持ちたくないときに便利です。例えばこの方法で作られた検索スクリプトはブックマークに適した、検索パラメータを持ったurlになります。
-no_xhtml
デフォルトでは、CGI.pm バージョン2.69以降はXHTML (http://www.w3.org/TR/xhtml1/)を出力します。-no_xhtmlプラグマはこの機能を止めます。この機能について、Michalis Kabrianis <kabrianis@hellug.gr>に感謝します。
-nph
これはCGI.pmにNPH(解析されないヘッダno parsed header)スクリプトに適したヘッダを作成させます。サーバにそのスクリプトがNPHであると告げるのと同じように他のことをする必要があるかも知れません。NPHスクリプトについては下記をご覧下さい。
-newstyle_urls
CGIパラメータ問い合わせ文字列の名前=値の組を、アンパサンドではなくセミコロンで分割します。例えば:
   ?name=fred;age=24;favorite_color=3

セミコロン区切りの問い合わせ文字列は常に受取られますが、 -newstyle_urls プラグマが指定されなければ、self_url()やquery_string()では出力されません。

これはバージョン2.64でデフォルトになりました。

-oldstyle_urls
CGIパラメータ問い合わせ文字列の名前=値の組を、セミコロンではなくアンパサンドで分割します。これはもはやデフォルトではありません。
-autoload
プログラム内の理解されないすべての関数が可能な評価のためにCGI.pmが参照されるようautoloaderをオーバーライドします。これにより、それらをシンボル・テーブルに加えることなく、すべてのCGI.pm関数を使うことが出来ます。これはメモリ消費を心配するmod_perlユーザに関連します。警告:-autoload が有効なとき"詩的モード(poetry mode)"(括弧のない関数)を使うことは出来ません。hrではなくhr()を使うか、use subs qw/hr p header/ のようなものをスクリプトの先頭に加えてください。
-no_debug
これはコマンド行処理機能をオフにします。HTMLを作成するためにCGI.pmをコマンド行から実行したいけれども、標準入力やコマンド行からのリクエストCGIパラメータを解析したくないならば、このプラグマを使ってください:
   use CGI qw(-no_debug :standard);
-debug
これはコマンド行処理機能をオンにします。コマンド行処理からCGI引数を読み込むことに加えて、CGI.pmは一旦停止し、STDINから引数を読み込もうとしまし、"(offline mode: enter name=value pairs on standard input)"というメッセージを出します。
 
さらなる詳細は「デバッグ」セクションをご覧ください。
-private_tempfiles
CGI.pmはアップロードされたファイルを処理することができます。通常、アップロードされたファイルはテンポラリ・ディレクトリにスプールされ、処理が終ると削除されます。しかし、これには「ファイル・アップロード」セクションでも説明しているように盗聴の危険性があります。それが秘密の情報であっても、アップロードの途中に他のCGIスクリプトの作者が覗き見ることができます。UNIXシステムでは、-private_tempfilesプラグマは、テンポラリ・ファイルを開かれると、何かデータが書込まれる前に、すぐに削除されるようにします。これにより盗聴の危険性を減らしますが、完全ではなりません。(まだ潜在的に可能な状態です)アタッカーに厳しく対応するためには、プログラムは一時ファイル名をやって来たHTTTPヘッダの32ビットチェックサムを計算することで選択します。

一時ファイルが他のCGIスクリプトが読むことが出来ないことを保証するには、スクリプトを実行するためにsuEXEC または CGI ラッパを使ってください。一時ファイルはモード 0600(ワールドもグループも読むことが出来ない)で作成されます。

一時ディレクトリは以下のアルゴリズムを使って選択されます:

    1. 現在のユーザ(例えば"nobody")がホーム・ディレクトリに"tmp"と
       いうディレクトリを持っていれば、それを使います(Unixシステムのみ)
    2. 環境変数TMPDIRがあれば、示された場所を使います
    3. そうでなければ、以下の場所を当たります /usr/tmp, /var/tmp, C:\temp,
    /tmp, /temp, ::Temporary Items, and \WWW_ROOT.

それぞれの場所はそれがディレクトリであるか、書きこみ可能かをチェックされます。そうでなければアルゴリズムは次の選択を挑戦します。


HTMLタグ関数のインポートのための特別な形式

メソッドの多くがHTMLを作成します。下記で説明するように、タグ関数は自動的に開始と終了の両方のタグを自動的に作成します。例えば:

  print h1('Level 1 Header');

は 以下のものを作成します。

  <H1>Level 1 Header</H1>

ときには開始と終了タグを自分自身で作成したいときがあるでしょう。この場合、以下のようにstart_タグ名とend_タグ名の形式を使うことができます:

  print start_h1,'Level 1 Header',end_h1;

いくつかの例外がありますが(下記で説明)、start_タグ名とend_タグ名関数はuse CGIしたときに自動的に作成されません。しかし、その名前の前にアスタリスクを置くか、あるいは代わりに"start_タグ名"または"end_タグ名"をインポート・リストに要求することによって、start/end 関数を作成したいタグを指定することができます。

例:

  use CGI qw/:standard *table start_ul/;

この例では、標準の関数に加えて以下の関数が作成されます:

  1. start_table() (<TABLE> タグを作成)
  2. end_table() (</TABLE> タグを作成)
  3. start_ul() (<UL> タグを作成)
  4. end_ul() (</UL> タグを作成)

動的ドキュメントの作成

CGI.pmの関数ほとんどは実行中にドキュメントを作成することを扱います。一般的にはまずHTTPヘッダを作成し、その後にドキュメントそのものがつきます。CGI.pmはHTMLを作成するのと同じくらい、多くのさまざまなHTTPヘッダを作成するための関数を提供します!GIFイメージの作成については、GD.pmモジュールをご覧ください。

これらの関数のそれぞれはHTMLやHTTPの一部を作成します。それらは直接出力できるので、ブラウザ・ウィンドウに表示したり、文字列を追加したり、後で使うようにファイルに保存したりといったことができます。


標準HTTPヘッダの作成:

通常、CGIスクリプトで最初にやることはHTTPヘッダを出力することです。これはブラウザに予想されるドキュメントのタイプを伝え、言語や有効期限、ドキュメントをキャッシュするかどうかといった他のオプションの情報を与えます。ヘッダは、サーバー・プッシュやペイ・パー・ビューといった特別な目的のために使われることもあります。

        print $query->header;
             -または-
        print $query->header('image/gif');
             -または-
        print $query->header('text/html','204 No response');
             -または-
        print $query->header(-type=>'image/gif',
                             -nph=>1,
                             -status=>'402 Payment required',
                             -expires=>'+3d',
                             -cookie=>$cookie,
                             -charset=>'utf-7',
                             -attachment=>'foo.gif',
                             -Cost=>'$2.00');

header()はContent-type:ヘッダを返します。もし選択すれば、独自のMIMEタイプを作成することができます。そうでなければデフォルトはtext/htmlです。オプションの2番目のパラメータはステータス・コードと人間が読むことができるメッセージを指定します。例えば、204、"No response"を指定すると、ブラウザに何もしないように伝えるスクリプトを作ることができます。

最後の例は、CGIメソッドへ引数を渡すための名前付き引数スタイルを示しています。理解されるパラメータは-type, -status, -expires, そして -cookieです。他の名前がついたパラメータはすべて、最初のハイフンを落とされて、ヘッダ・フィールドに変えられます、あなたが望むすべてのHTTPヘッダを指定することが可能です。内部のアンダースコアはハイフンに変換されます:

    print $query->header(-Content_length=>3002);

ほとんどのブラウザはCGIスクリプトからの出力をキャッシュしません。スクリプトが新たに呼び出されるたびに、ブラウザはページをリロードします。この動きは-expiresで変更することができます。このパラメータで絶対または相対の有効期間を指定すると、いくつかのブラウザとプロキシー・サーバは指定された有効期限まで、そのスクリプトの出力をキャッシュします。以下の形式はすべて、-expiresフィールドに対して適切です。

        +30s                              今から30秒
        +10m                              今から10分
        +1h                               今から1時間
        -1d                               昨日(つまり、できるだけ早く!)
        now                               直後に
        +3M                               3ヶ月間
        +10y                              10年間
        Thursday, 25-Apr-1999 00:40:33 GMT  指定された時刻と日付

-cookie パラメータはブラウザに、この後このスクリプトとのすべてのトランザクション間、"魔法のクッキー"を提供することを伝えます。Netscapeクッキーは有効期限のような面白い属性が入った特別なフォーマットを持っています。セッション・クッキーを作成し、取り出すためにはcookie()メソッドを使ってください。

-nph パラメータがtrue値に設定されれば、それはNPH(no-parse-header)スクリプトで機能するための正しいヘッダを出力させます。そのすべてのスクリプトがNPHであることを期待する、ある種のサーバで使うことは重要です。

-charset パラメータはブラウザに送信される文字セットを制御するために使うことが出来ます。与えられなければ、デフォルトはISO-8859-1です。副作用として、これはcharset()メソッドも設定します。

-attachment パラメータは添付にページを切り替えるために使うことが出来ます。ページを表示する代りに、ブラウザによってはファイルに保存するためのプロンプトを表示します。引数の値は保存されるファイルのための提案される名前です。これが機能するためには、-typeを"application/octet-stream"にしなければいけないかもしれません。


リダイレクション・ヘッダの作成

   print $query->redirect('http://somewhere.else/in/movie/land');

ときには、ドキュメントをあなた自身が作成するのではなく、おそらくURLは時刻やユーザの識別子をベースにより選択しながら、単にブラウザをどこかにリダイレクトしたいだけかもしれません。

redirect()関数はブラウザを他のURLにリダイレクトします。もしこのようなリダイレクトを使えば、headerも出力してはいけません

私が提案できる、1つのヒントはあなたのサイトの別のドキュメントへのリダイレクトを作成したとき、相対リンクは正しく機能しません。これは、いくつかのサーバが使うよく考えられた最適化によるものです。それを解決する方法はリダイレクトするドキュメントの(http:部分も含めた)フルのURLを使うことです。

名前付き引数も使うことができます:

    print $query->redirect(-uri=>'http://somewhere.else/in/movie/land',
                           -nph=>1);

-nph パラメータがtrue値に設定されれば、それはNPH(no-parse-header)スクリプトで機能するための正しいヘッダを出力させます。Microsoft Internet Information Server (訳者注:原文では Internet Explorer)のように、そのすべてのスクリプトがNPHであることを期待する、ある種のサーバで使うのは重要です。


HTMLドキュメント・ヘッダの作成

   print $query->start_html(-title=>'Secrets of the Pyramids',
                            -author=>'fred@capricorn.org',
                            -base=>'true',
                            -target=>'_blank',
                            -meta=>{'keywords'=>'pharaoh secret mummy',
                                    'copyright'=>'copyright 1996 King Tut'},
                            -style=>{'src'=>'/styles/style1.css'},
                            -BGCOLOR=>'blue');

HTTPヘッダを作成した後、ほとんどのCGIスクリプトはHTMLドキュメントの出力を始めます。start_html()ルーチンはページの見た目や動きを制御するたくさんのオプションの情報とともに、ページの先頭を作成します。

このメソッドは閉じられたHTMLヘッダと開かれた<BODY>タグを返します。全てのパラメータはオプションです。名前付きパラメータ形式で、理解されるパラメータは-title, -author, -base, -xbase そして -targetです(下記の説明をご覧ください)。Netscapeの非公式のBGCOLOR属性ような、指定されたすべての追加のパラメータは<BODY>タグに追加されます。追加のパラメータは前にハイフンをつけなければいけません。

引数-xbase は<BASE>タグを現在の位置から変えるためにHREFを提供することを許します。

    -xbase=>"http://home.mcom.com/";

すべての相対リンクは、このタグからの相対と解釈されます。

引数 -target はすべてのリンクとページ上のフォームのためのデフォルトのターゲット・フレームを指定することができます。これはNetscapeブラウザでのみ機能する標準でないHTTP機能です。これをどのように扱うかの詳細については、Netscapeのフレームについてのドキュメントをご覧ください。

    -target=>"answer_window"

すべての相対リングはこタグの相対だと解釈されます(訳者注:おそらく不要(?_?))。-meta 引数でヘッダに任意のメタ情報を追加します。この引数はメタ情報の名前/値の組が入った連想配列へのリファレンスを期待します。これらは以下のような、ヘッダでの一連の<META>タグに変わります:

    <META NAME="keywords" CONTENT="pharaoh secret mummy">
    <META NAME="description" CONTENT="copyright 1996 King Tut">

<META>タグのHTTP-EQUIVタイプを作るためには、以下で詰めイする-headを使ってください。

-styleタグはあなたのコードにカスケーディング・スタイルシートを入れるために使われます。さらに詳細な情報は「カスケーディング・スタイルシート」のセクションをご覧ください。

-lang 引数は<HTML>タグにlanguage属性を入れるために使われます。指定されなかったときのデフォルトはUS Englishのための"en-US"です。例:

    print $q->header(-lang=>'fr-CA');

-headタグで他の任意のHTML要素を<HEAD>セクションに置くことができます。例えば、あまり使われない<LINK>要素をHEADセクションに置くには、これを使ってください:

    print start_html(-head=>Link({-rel=>'next',
                                  -href=>'http://www.capricorn.com/s2.html'}));

HTML要素を<HEAD>セクションに入れるためには、単に配列リファレンスを渡してください:

    print start_html(-head=>[ 
                             Link({-rel=>'next',
                                   -href=>'http://www.capricorn.com/s2.html'}),
                             Link({-rel=>'previous',
                                   -href=>'http://www.capricorn.com/s1.html'})
                             ]
                     );

そしてここでHTTP-EQIV<META>タグの作成法を示します:

      print header(-head=>meta({-http_equiv => 'Content-Type',
                                -content    => 'text/html'}))

JAVASCRIPTING: -script, -noScript, -onLoad, -onMouseOver, -onMouseOut そして -onUnload パラメータがNetscape JavaScript呼出しをページに追加するために使われます。-scriptはJavaScript関数定義が入ったテキストのブロックを示さなければなりません。このブロックは(HTTPではなく)<HTML>の内部の<SCRIPT>ブロックに置かれます。たとえページが完全にロードされる前にユーザがストップ・ボタンを押したとしても、すべてのJavaScript関数が置かれるチャンスをあなたのページに与えるために、そのブロックはヘッダに置きます。CGI.pmはJavaScriptを知らないブラウザがそのコードで窒息しないような方法で、そのスクリプトをフォーマットしようとします:それにも関らず、残念ながらChimera for Unixのように混乱してしまうブラウザがいくつかあります。

-onLoad-onUnload パラメータは、それぞれブラウザによってそのページが開かれたときと閉じられたときに実行されるJavaScriptコードを示します。通常これらのパラメータは-script フィールドで定義された関数を呼びます:

      $query = new CGI;
      print $query->header;
      $JSCRIPT=<<END;
      // Ask a silly question
      function riddle_me_this() {
         var r = prompt("What walks on four legs in the morning, " +
                       "two legs in the afternoon, " +
                       "and three legs in the evening?");
         response(r);
      }
      // Get a silly answer
      function response(answer) {
         if (answer == "man")
            alert("Right you are!");
         else
            alert("Wrong!  Guess again.");
      }
      END
      print $query->start_html(-title=>'The Riddle of the Sphinx',
                               -script=>$JSCRIPT);

JavaScriptを持っていないブラウザ(あるいはJavaScriptがオフになっているブラウザ)で表示されるいくつかのHTMLテキストを渡すためには-noScript パラメータを使ってください。

Netscape 3.0 は、LANGUAGEとSRCを含めて、<SCRIPT>タグの多くの属性を理解します。後者はソースを持った各ページに散乱させるのではなく、JavaScriptpコードをファイルまたはCGIスクリプトに保管することを可能にするため、特に興味深いものです。この属性を使うためには、-script パラメータに1つまたはそれ以上の-language、-srcまたは-codeが入ったハッシュ・リファレンスを渡します:

    print $q->start_html(-title=>'The Riddle of the Sphinx',
                         -script=>{-language=>'JAVASCRIPT',
                                   -src=>'/javascript/sphinx.js'}
                         );
    print $q->(-title=>'The Riddle of the Sphinx',
               -script=>{-language=>'PERLSCRIPT',
                         -code=>'print "hello world!\n;"'}
               );

最後の機能は複数の<SCRIPT>セクションをヘッダに入れることを可能にします。配列リファレンスとしてスクリプト・セクションのリストを渡すだけです。これはJavaScriptの異なる方言のための異なるソースを指定することができます。例えば:

     print $q->start_html(-title=>'The Riddle of the Sphinx',
                          -script=>[
                                    { -language => 'JavaScript1.0',
                                      -src      => '/javascript/utilities10.js'
                                    },
                                    { -language => 'JavaScript1.1',
                                      -src      => '/javascript/utilities11.js'
                                    },
                                    { -language => 'JavaScript1.2',
                                      -src      => '/javascript/utilities12.js'
                                    },
                                    { -language => 'JavaScript28.2',
                                      -src      => '/javascript/utilities219.js'
                                    }
                                 ]
                             );
     </pre>

これがちょっとヒドいと見えれば、私のアドバイスを聞いてストレートなCGIスクリプトで我慢してください。

JavaScriptについての更なる情報については

   http://home.netscape.com/eng/mozilla/2.0/handbook/javascript/

をご覧ください。

古いスタイルの位置によるパラメータは以下の通りです。

パラメータ
  • 1 タイトル
  • 2. 作者のe-mailアドレス(もしあれば<LINK REV="MADE"> タグを作成します)
  • 3. <BASE>タグをヘッダに入れたければ、'true'フラグ。これはドキュメントが動いたけれども、ドキュメントの階層は移植しないとき、相対アドレスを絶対アドレスに解決するのを助けます。注意して使ってください。
  • 4, 5, 6...

    他のすべてのパラメータは<BODY>タグに入れたいものです。ここは色や壁紙のパターンのような、Netscape拡張を置くのによい場所です。


  • HTMLドキュメントの終わり:

            print $query->end_html
    

    </BODY></HTML> タグを出力することでHTMLドキュメントを終らせます。


    状態情報を保持しながら自分自身を参照するURLの作成:

        $myself = $query->self_url;
        print q(<A HREF="$myself">I'm talking to myself.</A>);
    

    self_url()は選択されたとき、今動いているすべての状態情報でこのスクリプトを再度呼び出すURLを返します。内部のアンカーを使ってドキュメントの中でジャンプしたいけれども、フォームの現在の内容を壊したくないときにとても有効です。以下のようにするとうまくいきます。

         $myself = $query->self_url;
         print "<A HREF=$myself#table1>See table 1</A>";
         print "<A HREF=$myself#table2>See table 2</A>";
         print "<A HREF=$myself#yourself>See for yourself</A>";
    

    何を返すかを更に制御したければ、代わりにurl()メソッドを使ってください。

    処理されていない問い合わせ文字列はquery_string()で取り出すこともできます:

        $the_string = $query->query_string;
    

    スクリプトのURLを取得する

        $full_url      = $query->url();
        $full_url      = $query->url(-full=>1);  #alternative syntax
        $relative_url  = $query->url(-relative=>1);
        $absolute_url  = $query->url(-absolute=>1);
        $url_with_path = $query->url(-path_info=>1);
        $url_with_path_and_query = $query->url(-path_info=>1,-query=>1);
    

    url() はスクリプトのURLをさまざまなフォーマットで返します。何も引数がなく呼ばれれば、ホスト名とポート番号を含んだURLのフルの形式を返します。

        http://your.host.com/path/to/script.cgi
    

    You can modify this format with the following named arguments:

    absolute
    trueであれば、絶対URLを作成します。例えば
        /path/to/script.cgi
    
    -relative
    相対URLを作成します。異なるパラメータでスクリプトをもう一度呼びたいときに、これは便利です。例えば:
        script.cgi
    
    -full
    何も引数なしに呼んだのとまったく同じ、フルのURLを作成します。これは-relative と-absoluteを上書きします。
    -path (-path_info)
    URLに追加のパス情報を追加します。これは-full, -absolute または-relativeと一緒にすることができます。 -path_info がシノニムとして提供されます。
    -query (-query_string)
    URLに問い合わせ文字列を追加します。これは-full, -absolute または -relativeと一緒にすることができます。-query_string がシノニムとして提供されます。

    混合POSTとURLパラメータ

       $color = $query-&gt;url_param('color');
    

    問い合わせ文字列(引数が後ろについた"?"マーク)が入ったURLへPOSTするフォームを作成することによりフォームと同じように、スクリプトにはCGIパラメータをURLで受け取ることは可能です。param() メソッドは、URLの問い合わせ文字列を無視し、常にPOSTされたフォームの内容を返します。URLパラメータを取り出すためにはurl_param()メソッドを呼び出してください。param()と同じように使ってください。大きな違いはパラメータを読むことができることで、設定はできません。

    いかなる状況においても、URL問い合わせ文字列の内容がPOSTされたフォームの同じ名前のCGIパラメータを干渉することはありません。URL問い合わせ文字列とGETメソッドでサブミットされるフォームとを混ぜてみると、その結果はあなたが予想しなかったことになるでしょう。


    標準HTML要素の作成:

    HTML 3 とHTML 4タグですべてでなければ、CGI.pmは一般的なHTMLショートカットメソッドの大半を定義します。HTMLショートカットは1つのHTMLの後に名づけられ、出力でき、好きなように扱うことができるHTMLテキストの一部を返します。各ショートカットは文字列に追加したり、ファイルの保存したり、または最も一般的にはブラウザ・ウィンドウで表示するように出力することができるHTMLコードを返します。

    この例はHTMLメソッドをどのように使うかを示します:

       $q = new CGI;
       print $q->blockquote(
                         "Many years ago on the island of",
                         $q->a({href=>"http://crete.org/";},"Crete"),
                         "there lived a Minotaur named",
                         $q->strong("Fred."),
                        ),
           $q->hr;
    

    この結果は以下のHTMLコードになります(読みやすくするために改行を入れています)

       <blockquote>
       Many years ago on the island of
       <a HREF="http://crete.org/";>Crete</a> there lived
       a minotaur named <strong>Fred.</strong> 
       </blockquote>
       <hr>
    

    HTMLショートカットの呼出しの書き方が不格好だと思えば、名前空間にインポートし、オブジェクト的な書き方を完全に無くすことができます(詳細は次のセクションをご覧ください):

       use CGI ':standard';
       print blockquote(
          "Many years ago on the island of",
          a({href=>"http://crete.org/";},"Crete"),
          "there lived a minotaur named",
          strong("Fred."),
          ),
          hr;
    

    HTMLショートカットに引数を与える

    HTMLメソッドは0、1つまたは複数の引数を受け取ります。もし引数を与えなければ、1つのタグを得ます:

       print hr;    #  <HR>
    

    もし1つまたは複数の文字列引数を与えれば、スペースでつなげられ、開始と終了タグに囲まれます:

       print h1("Chapter","1"); # <H1>Chapter 1</H1>"
    

    もし最初の引数が連想配列リファレンスであれば、その連想配列のキーと値はHTMLタグの属性になります:

       print a({-href=>'fred.html',-target=>'_new'},
          "Open a new frame");
    
                <A HREF="fred.html",TARGET="_new">Open a new frame</A>
    

    もしそうしたければ、属性名の前につくダッシュをはずすことができます:

       print img {src=>'fred.gif',align=>'LEFT'};
    
               <IMG ALIGN="LEFT" SRC="fred.gif">
    

    HTMLタグ属性が引数を持たないこともあります。例えば順序付きリストはCOMPACTとして印をつけることができます。この書き方はundef文字列を示す引数になります:

       print ol({compact=>undef},li('one'),li('two'),li('three'));
    

    CGI.pmバージョン2.41より以前では、空('')文字列を属性引数として与えることはundefを与えるのと同じでした。しかし、これは<IMG ALT="">形式のタグを作りたい人たちに合わせるために変更されました。違いはこれらの2つのコードで示されます:

       コード                   結果
       img({alt=>undef})      <IMG ALT>
       img({alt=>''})         <IMT ALT="">
    

    HTMLショートカットの分配されるプロパティ

    HTMLショートカットの素晴らしい機能の1つにそれらが分配されることがあります。リストへのリファレンスが入った引数を与えると、そのタグはリストの各要素をまたがって分配されます。例えば、順序付きのリストを作る方法の1つを以下に示します:

       print ul(
                 li({-type=>'disc'},['Sneezy','Doc','Sleepy','Happy'])
               );
    

    これは結果として以下のようなHTML出力になります:

       <UL>
         <LI TYPE="disc">Sneezy</LI>
         <LI TYPE="disc">Doc</LI>
         <LI TYPE="disc">Sleepy</LI>
         <LI TYPE="disc">Happy</LI>
       </UL>
    

    これはテーブルを作るのとにとても便利です。例えば:

       print table({-border=>undef},
               caption('When Should You Eat Your Vegetables?'),
               Tr({-align=>CENTER,-valign=>TOP},
               [
                  th(['Vegetable', 'Breakfast','Lunch','Dinner']),
                  td(['Tomatoes' , 'no', 'yes', 'yes']),
                  td(['Broccoli' , 'no', 'no',  'yes']),
                  td(['Onions'   , 'yes','yes', 'yes'])
               ]
               )
            );
    

    HTMLショートカットとリストの挿入

    この小さなコードについて考えてみてください:

       print blockquote(em('Hi'),'mom!'));
    

    これは通常に、おそらく期待した文字列を返します、すなわち:

       <BLOCKQUOTE><EM>Hi</EM> mom!</BLOCKQUOTE>
    

    要素"Hi"と要素"mom!"の間のスページに注意してください。CGI.pmは配列を間に入れた場所に追加のスペースをおきます。これは特別な$"変数により制御されます。時には、例えば、一連のイメージの並べようとしているときなど、この追加のスペースはあなたの望んでいたものではありません。この場合、$"を空文字列に変更することによって簡単に変更することができます。

       {
          local($") = '';
          print blockquote(em('Hi'),'mom!'));
        }
    

    コードをここで示したようにブロックにいれることを提案します。そうしなければ明示的にリセットするまで、$"の変更が後のコードに影響を与えます。


    標準ではないHTMLショートカット

    いくつかのHTMLタグは多様性のために標準パターンに従いません。

    comment() はHTMLコメント(<!-- comment -->)を作成します。以下のように呼び出してください

        print comment('here is my comment');
    

    組み込みPerl関数とぶつかるので、以下の関数は先頭の文字が大文字になります:

        Select
        Tr
        Link
        Delete
        Accept
        Sub
    

    さらにstart_html()、end_html()、start_form()、end_form()、start_multipart_form()そしてすべてのフォームタグは特別です。それぞれのセクションをご覧ください。


    HTMLの自動エスケープ

    デフォルトでは、フォーム作成関数用により作成されるすべてのHTMLはescapeHTML()という関数を通ります:

    $escaped_string = escapeHTML("unescaped string");
    文字列に入っているHTMLフォーマットの文字をエスケープ

    文字セットISO-8859-1(デフォルト)を指定すると、標準のHTMLエスケープのルールが使われます。"<"文字は"&lt;"、">"は"&gt;","&"は"&amp"、クオート文字は"&quot"になります。さらに0x8bと0x9b文字、これは多くのWindowsベースのブラウザは左と右の斜め括弧に解釈されるのですが、は数値のHTMLエントリ("&#139"と"&#155")に置きかえられます。charset()メソッドを明示的に呼び出すか、header()に-charset引数を渡すことにより、手で文字設定を変更したら、CGI.pmはすべての可能性のあるエンコーディングのための検索テーブルを持たないので、すべての文字は数値エントリによりよって置きかえられます。

    h1()のような自動エスケープは他のショートカットに適用されません。人々がゲストブックなどにいれるかもしれない困った書き方からあなたのページを守るために、信用できないデータにescapeHTML()を呼ぶべきです。文字セットを変更するには、charset()を使ってください。自動エスケープを完全に止めるには、autoescape()を使ってください:

    $charset = charset([$charset]);
    現在の文字セットを取得あるいは設定します
    $flag = autoEscape([$flag]);
    自動エスケープ・フラグの値を取得または設定します。

    HTMLをきれいに出力(PRETTY-PRINTING)

    デフォルトでは、これらの関数により作成されるすべてのHTMLは、改行やインデントのない1つの長い行になります。これは汚いですが、ドキュメントの大きさを10%−20%減らします。きれいな出力を取得するには、Brian Paulsenによって作成されたサブクララスであるCGI::Prettyを使ってください。


    フォームの作成:

    一般的な注意点 様々なフォーム・作成メソッドはすべて、呼び出し元に要求されたフォーム要素を作成するタグが入った文字列を返します。あなたはこれらの文字列を実際に出力する責任があります。それはこのように設定されるので、フォーム要素の周りにフォーマットするタグを置くことが出来ます。

    他の注意点 フォームに指定するデフォルトの値は、(問い合わせ文字列がない時)スクリプトが呼び出された最初のときだけ使われます。その後のスクリプト呼び出しでは(問い合わせ文字列があるとき)、たとえ空白であっても前の値が使われます。

    前の値からフィールドの値を変更したければ2つの選択肢があります:

    (1) 設定するためにparam()メソッドを呼び出す。

    (2) -override (別名 -force) パラメータを使う(バージョン2.15での新しい機能)。これは前の値に関係なく、デフォルトの値が使われるように強制します:

       print $query->textfield(-name=>'field_name',
                               -default=>'starting value',
                               -override=>1,
                               -size=>50,
                               -maxlength=>80);
    

    さらにもう1つの注意点 デフォルトでは、フォーム要素のテキストとラベルはHTMLルールにしたがってエスケープされます。つまりボタンのためのラベルとして"<CLICK ME>"を安全に使うことが出来ます。しかしそのために、フィールドにÁ のような特殊なHTML文字の並びをいれることができません。自動的なエスケープをオフにしたければ、CGIオブジェクトを作成したすぐあとにautoEscape()メソッドをfalseで呼び出してください:

       $query = new CGI;
       $query->autoEscape(undef);
    

    ISINDEXタグの作成

       print $query->isindex(-action=>$action);
    
             -または-
    
       print $query->isindex($action);
    

    <ISINDEX> タグを出力します。あまり面白くはありません。パラメータ -actionは、問い合わせを処理するスクリプトのURLを指定します。デフォルトでは現在のスクリプトで問い合わせを処理します。


    フォームの開始と終了

        print $query->start_form(-method=>$method,
                                -action=>$action,
                                -enctype=>$encoding);
          <... さまざまなフォームの内容 ...>
        print $query->endform;
    
            -または-
    
        print $query->start_form($method,$action,$encoding);
          <... さまざまなフォームの内容 ...>
        print $query->endform;
    

    startform()は<FORM>タグを指定したオプションのメソッド、アクション、フォーム・エンコーディングと一緒に返します。デフォルトは以下の通りです:

        method: POST
        action: このスクリプト
        enctype: application/x-www-form-urlencoded
    

    endform()は</FORM>タグを返します。

    startform()のenctype引数はブラウザがフォームをサーバに送信する前にフォームの様々なフィールドをどのようにパッケージするかを伝えます。以下の2つの値が指定できます:

    注意: このメソッドは以前startform()という名前でした。そしてstartform()はまだエリアスとして理解されます。

    application/x-www-form-urlencoded
    これはNetscape 2.0より前のすべてのブラウザによって使われた古いタイプのエンコーディングです。多くのCGIスクリプトと互換性があり、テキスト・データが入った短いフィールドに適しています。便利なようにCGI.pmはこのエンコーディング・タイプの名前を$CGI::URL_ENCODEDに格納しています。
    multipart/form-data
    これはNetscape 2.0によって導入された新しいタイプのエンコーディングです。これは非常に大きなフィールドを持ったフォームやバイナリ・データを転送するフォームに適しています。最も重要なことは、これはNetscape 2.0 フォームの"ファイル・アップロード"機能を可能にすることです。便利なようにCGI.pmはこのエンコーディング・タイプの名前を&CGI::MULTIPART に格納しています。

    CGI.pmやそれらを扱うように設計されているほかのライブラリを使わなければ、CGIスクリプトはこのタイプのエンコーディングを使うフォームを簡単には解釈できません。

    互換性のため、start_form()メソッドはデフォルトでは古い形を使います。デフォルトで新しい形式を使いたければ、start_form()の代りにstart_multipart_form() を呼ぶことが出来ます。

    JAVASCRIPTING: -name-onSubmit パラメータがJavaScriptでの使用のために提供されています。-nameパラメータはJavaScript関数によって識別され、扱えるようにフォームの名前を与えます。-onSubmitはフォームがサーバにサブミットされる直前に実行されるJavaScript関数を示さなければなりません。この機会を使って、フォームの内容に矛盾がないか、すべて入っているかをチェックすることができます。何かおかしな事を見つけたら、アラートボックスを表示したり、自分でそれを修正するかもしれません。この関数からfalseを返すことによってサブミットを中止することが出来ます。

    通常JavaScriptの固まりはHTMLヘッダでの<SCRIPT>ブロックで定義され、-onSubmitはこれらの関数呼び出しの1つを指します。詳細についてはstart_html()をご覧下さい。


    テキスト・フィールドの作成

        print $query->textfield(-name=>'field_name',
                                -default=>'starting value',
                                -size=>50,
                                -maxlength=>80);
            -または-
    
        print $query->textfield('field_name','starting value',50,80);
    

    textfield()はテキスト入力フィールドを返します。

    パラメータ
  • 最初のパラメータは必須で、フィールド名です (-name)。
  • 2番目のパラメータはオプションで、フィールド内容のデフォルト文字列です (-default)。
  • 3番目のパラメータはオプションで、文字数によるフィールドの大きさです (-size)。
  • 4番目のパラメータはオプションで、そのフィールドが受けつける最大文字数です (-maxlength)。
  • これらすべてのメソッドでは、フィールドはそのスクリプトの以前の呼び出しからの内容で初期化されます。フォームが処理されたとき、テキスト・フィールドの値は以下のように取り出すことが出来ます:

           $value = $query->param('foo');
    

    そのスクリプトが1度呼び出された後に初期値でリセットしたければ、以下のようにすることが出来ます:

           $query->param('foo',"I'm taking over this value!");
    

    2.15での新機能:フィールドをその前の値にしたくなければ、-override(別名 -force)パラメータを使うことにより、現在の値に強制することが出来ます。

        print $query->textfield(-name=>'field_name',
                                -default=>'starting value',
                                -override=>1,
                                -size=>50,
                                -maxlength=>80);
    

    JAVASCRIPTING: JavaScriptイベント・ハンドラを登録するために、-onChange-onFocus-onBlur-onMouseOver-onMouseOutそして-onSelect パラメータを提供することが出来ます。onChangeハンドラはユーザがテキスト・フィールドの内容を変更するといつでも呼び出されます。よければテキストの有効性チェックをすることができます。onFocusとonBlurはそれぞれ、挿入ポイントがテキスト・フィールドに入ったとき、テキスト・フィールドから抜けたときに呼ばれます。onSelectは選択されているテキストの部分を変えたときに呼ばれます。


    大きなテキスト・フィールドの作成

       print $query->textarea(-name=>'foo',
                              -default=>'starting value',
                              -rows=>10,
                              -columns=>50);
    
            -or
    
       print $query->textarea('foo','starting value',10,50);
    

    textarea()は、まるでテキストフィールドのようですが、複数行テキスト入力ボックスのために行と列を指定することが出来ます。そのフィールドに開始する値を与えることができます。それは長くしたり、複数行にすることができます。

    JAVASCRIPTING: -onChange, -onFocus, -onBlur , -onMouseOver, -onMouseOut, そして -onSelect パラメータが理解されます。textfield()をご覧下さい。


    パスワード・フィールドの作成

       print $query->password_field(-name=>'secret',
                                    -value=>'starting value',
                                    -size=>50,
                                    -maxlength=>80);
            -または-
    
       print $query->password_field('secret','starting value',50,80);
    

    password_field()は、その内容がwebページでは星印で表示されることを除いては、textfiled()と同じです。

    JAVASCRIPTING: -onChange, -onFocus, -onBlur, -onMouseOver, -onMouseOut そして -onSelect パラメータが理解されます。textfield()をご覧下さい。


    ファイル・アップロード・フィールドの作成

        print $query->filefield(-name=>'uploaded_file',
                                -default=>'starting value',
                                -size=>50,
                                -maxlength=>80);
            -または-
    
        print $query->filefield('uploaded_file','starting value',50,80);
    

    filefield()はNetscape2.0ブラウザのためのファイル・アップロード・フィールドを返します。利点をすべて生かすためには、そのフォームに新しいマルチパート・エンコーディング・スキームを使わなければなりません。これはエンコーディング・タイプを$CGI::MULTIPARTstart_form()を呼び出すか、普通のstart_form()の代りに新しいメソッドstart_multipart_form()を呼び出すかのどちらかで行うことが出来ます。

    パラメータ
  • 最初のパラメータは必須で、フィールド名です(-name) 。
  • 2番目のパラメータはオプションで、デフォルトのファイル名として使われるフィールド内容のための初期値です (-default)。

    セキュリティ上の理由から、ブラウザはこのフィールドには注意を払いません、そのため初期値は常にブランクになります。さらに悪いことに、フィールドはその"なかなか変わらない"動きを失い、前の内容を忘れてしまいます。しかしHTML仕様では初期値フィールドは要求されています、多分いくつかのブラウザは最終的にはそれをサポートでしょう。

  • 3番目のパラメータはオプションで、フィールドの大きさを文字数で指定します (-size)。
  • 4番目のパラメータはオプションで、そのフィールドが受取る最大文字数です (-maxlength)。
  • フォームが処理されると、param()を呼ぶことによって入力されたファイル名を取得することが出来ます:

           $filename = $query->param('uploaded_file');
    

    ブラウザによってちょっとずつ違う名前を返します。あるブラウザはファイル名だけを返します。あるものはユーザのマシンのパスの書き方を使ったファイルへのフルパスを返します。いずれにせよ返される名前は常にユーザのマシンでのファイル名で、CGI.pmがアップロードのスプーリングのさいに作成する一時ファイルの名前には関連しません(以下をご覧ください)。

    返されるファイル名はファイル・ハンドルでもあります。標準のPerlファイル読み込み呼び出しを使ってファイルの内容を読むことが出来ます:

            # テキストファイルを読み込み、出力します
            while (<$filename>) {
               print;
            }
    
            # バイナリ・ファイルをどこか安全なところへコピーします
            open (OUTFILE,">>/usr/local/web/users/feedback");
            while ($bytesread=read($filename,$buffer,1024)) {
               print OUTFILE $buffer;
            }
    

    しかしアップロード・フィールドの2つの性質に絡んで問題があります。use strictを使っていると、Perlは文字列をファイルハンドルとして使うと文句をいうでしょう。これはファイルの読み込みをno strictプラグマを含んだブロックにいれることで回避することが出来ます。さらに深刻なことは、リモート・ユーザがアップロード・フィールドにゴミをいれると、param()は文字列ではあっても、ファイルハンドルではない可能性があります。

    安全のためには、upload()関数(バージョン2.47での新機能)を使ってください。アップロード・フィールドでこれを呼ぶと、upload()はファイルハンドル、もしくはパラメータが正しいファイルハンドルでなければundefを返します。

         $fh = $query->upload('uploaded_file');
         while (<$fh>) {
               print;
         }
    

    これは推奨される表現です。

     

    ファイルがアップロードされるとき、ブラウザは通常、ヘッダのフォーマットの中にいくつかの情報を一緒に送信します。その情報には通常、MIME content typeが入っています。将来のブラウザは他の情報も送信するかもしれません(変更日や大きさなのような)。この情報を取り出すためには、uploadInfo()を呼び出してください。それはすべてのドキュメント・ヘッダが入った連想配列へのリファレンスを返します。

           $filename = $query->param('uploaded_file');
           $type = $query->uploadInfo($filename)->{'Content-Type'};
           unless ($type eq 'text/html') {
              die "HTML FILES ONLY!";
           }
    

    "text"と"binary"データ・モードを理解するマシンを使っていれば、それをいつ、どのように使うかを確認してください(ラクダ本をご覧下さい)。そうでなければ、ファイル・アップロードの間にバイナリファイルがおかしくなるのを発見するでしょう。

    ときどきアップロードされたファイルを解析している途中に問題が発生します。それは通常ユーザがアップロードが完了する前に"Stop"を押したときにおこります。

    この場合、CGI.pmはアップロードされたファイルの名前の代りにundefをにをcgi_error()に文字列"400 Bad Request (malformed multipart POST)"を設定します。このエラーメッセージはブラウザに送信するステータス・コードに入れることができるように考えられています。例えば:

       $file = $query->upload('uploaded_file');
       if (!$file && $query->cgi_error) {
          print $query->header(-status=>$query->cgi_error);
          exit 0;
       }
    

    もしも望むなら、エラーについて不満をいうために独自のHTMLページを自由に作ることができます。

    JAVASCRIPTING: -onChange, -onFocus, -onBlur, -onMouseOver, -onMouseOut そして -onSelect パラメータが理解されます。詳細はtextfield()をご覧下さい。


    ポップアップ・メニューの作成

       print $query->popup_menu('menu_name',
                                ['eenie','meenie','minie'],
                                'meenie');
    
          -または-
    
       %labels = ('eenie'=>'your first choice',
                  'meenie'=>'your second choice',
                  'minie'=>'your third choice');
       print $query->popup_menu('menu_name',
                                ['eenie','meenie','minie'],
                                'meenie',\%labels);
    
            -または (名前付きパラメータ形式)-
    
       print $query->popup_menu(-name=>'menu_name',
                                -values=>['eenie','meenie','minie'],
                                -default=>'meenie',
                                -labels=>\%labels);
    

    popup_menu()はメニューを作成します。

    1. 最初のパラメータは必須で、メニューの名前です (-name)。
    2. 2番目の引数(-values)は必須で 、メニューでのメニュー項目が入った配列リファレンスです。例のように無名配列をメソッドに渡すことが出来ます。また"\@foo"のように名前付き配列へのリファレンスにすることも出来ます.
    3. 3番目の引数(-default)はオプションで、デフォルトで選択されるメニューの名前です。指定されなければ最初の項目がデフォルトです。前に選択された値が問い合わせをまたがって維持されます。
    4. 4番目のパラメータ (-labels)はオプションで、ユーザに見えるラベルのための値とスクリプトに返される値とを違うものにしたい人のために提要されます。メニューの値とユーザに見えるラベルとを関連付ける連想配列へのポインタです。このパラメータを空にしておくと、デフォルトでメニューの値は表示されたものになります(もしそうしたければラベルを未定義にしておくこともできます)

    フォームが処理されるとき、ポップアップ・メニューの選択された値は以下のようにして取り出すことが出来ます:

          $popup_menu_value = $query->param('menu_name');
    

    JAVASCRIPTING: popup_menuは以下のイベント・ハンドラを理解します:-onChange, -onFocus, -onMouseOver, -onMouseOut, そして-onBlur。いつこれらのハンドラが呼ばれるかの詳細はtextfield()をご覧下さい。


    スクローリング・リストの作成

       print $query->scrolling_list('list_name',
                                    ['eenie','meenie','minie','moe'],
                                    ['eenie','moe'],5,'true');
          -または-
    
       print $query->scrolling_list('list_name',
                                    ['eenie','meenie','minie','moe'],
                                    ['eenie','moe'],5,'true',
                                    \%labels);
    
            -または-
    
       print $query->scrolling_list(-name=>'list_name',
                                    -values=>['eenie','meenie','minie','moe'],
                                    -default=>['eenie','moe'],
                                    -size=>5,
                                    -multiple=>'true',
                                    -labels=>\%labels);
    

    scrolling_list()はスクローリング・リストを作成します。

    パラメータ:
  • 最初と2番目の引数はリストの名前(-name) と値 (-values)です。ポップアップメニュー(訳者注:スクローリングリストの間違いらしい)では、2番目の引数は配列リファレンスでなければなりません。
  • 3番目の引数(-default)はオプションで、デフォルトで選択される値が入ったリストへのリファレンスか、選択される1つの値のどちらかにすることができます。この引数がないか未定義であれば、リストがはじめて表示されたときには何も選択されません。名前付きパラメータのバージョンでは、このパラメータにシノニム"-defaults"を使うことが出来ます。
  • 4番目の引数はオプションで、リストの大きさです (-size)。
  • 5番目の引数はオプションで、同時に複数の選択を許すためにはtrueを設定します (-multiple)。そうでなければ一度には1つのだけが許されます。
  • 6番目の引数はオプションで、リスト要素のための長いユーザに見えるラベルが入った連想配列へのポインタです (-labels)。なければ、値(values)が表示されます。
  • このフォームが処理されるとき、選択されたリスト要素はパラメータ名'list_name'でのリストとして返されます。選択された要素の値は以下のようにして取り出すことが出来ます:

          @selected = $query->param('list_name');
    

    JAVASCRIPTING: scrolling_list()は以下のイベント・ハンドラを理解します: -onChange, -onFocus, -onMouseOver, -onMouseOut そして -onBlur。 いつこれらのハンドラが呼ばれるかの説明はtextfield()をご覧下さい。


    関連付けられたチェックボックスのグループの作成

       print $query->checkbox_group(-name=>'group_name',
                                    -values=>['eenie','meenie','minie','moe'],
                                    -default=>['eenie','moe'],
                                    -linebreak=>'true',
                                    -labels=>\%labels);
    
       print $query->checkbox_group('group_name',
                                    ['eenie','meenie','minie','moe'],
                                    ['eenie','moe'],'true',\%labels);
    
       HTML3互換ブラウザのみ:
    
       print $query->checkbox_group(-name=>'group_name',
                                    -values=>['eenie','meenie','minie','moe'],
                                    -rows=2,-columns=>2);
    

    checkbox_group()は同じ名前により関連付けられたチェックボックスのリストを作成します。

    パラメータ:
  • 最初と2番目の引数はそれぞれ、チェックボックスの名前と値 (-name と -values)です。ポップアップ・メニューと同じように、2番目の引数は配列リファレンスでなければなりません。これらの値は、チェックボックスの隣に出力されるユーザが読むことが出来るラベルであり、また問い合わせ文字列でスクリプトに渡される値でもあります。
  • 3番目の引数(-default)はオプションで、デフォルトでチェックされる値の入ったリストへのリファレンスかチェックされる1つの値のどちらかにすることができます。この引数がないか、未定義であれば、リストが最初に表示されたときには何も選択されません。
  • 4番目の引数 (-linebreak)はオプションで、trueに設定されると垂直なリストとして表示されるようにチェックボックスの間に改行をいれます。そうでなければ水平に一緒になって並べられます。
  • 5番目の引数はオプションで、チェックボックスの値とチェックボックスの隣に出力されるユーザに見えるラベルとを関連付ける連想配列へのポインタです(-labels)。与えられなければ値(values)がデフォルトとして使われます。
  • (ネットスケープのような)HTML3互換ブラウザ の利点として、オプションのパラメータとして -rows, と -columnsを取ることができます。これらのパラメータは、checkbox_groupを指定された数の行と列でフォーマットされたチェックボックス・グループが入ったHTML3互換のテーブルを返させるようにします。そうしたければ、-columnsだけを与えることもできます;check_groupは正しい行数をあなたに代って計算します。

    返されるテーブルでの行と列のヘッダを入れるために、 -rowheaders-colheaders パラメータを使うことが出来ます。これらは両方とも使用するヘッダの配列へのポインタを受取ります。そのヘッダは単なる飾りです。チェックボックスの解析を理解しません -- それらはまだ名前がついた1つのユニットです。

  •  

    フォームが処理されるとき、すべてのチェックされたボックスはパラメータ名'group_name'のリストとして返されます。"on"の値のチェックボックスは以下のようにして取り出すことが出来ます:

          @turned_on = $query->param('group_name');
    

    checkbox_groupによって返される値は実際にはボタン要素の配列です。以下のようにして、それらを取得し、テーブル、リストその他の作成方法で使うことが出来ます:

        @h = $query->checkbox_group(-name=>'group_name',-values=>\@values);
        &use_in_creative_way(@h);
    

    JAVASCRIPTING: checkbox_group()は-onClick パラメータを理解します。これは、そのグループの中のボタンのどれかをユーザがクリックするたびに実行される、JavaScriptコードの一部、あるいは関数を指定します。"this"変数を使って、クリックされたボタンの識別子を取り出すことが出来ます。


    独立したチェックボックスの作成

        print $query->checkbox(-name=>'checkbox_name',
                               -checked=>'checked',
                               -value=>'ON',
                               -label=>'CLICK ME');
    
            -または-
    
        print $query->checkbox('checkbox_name','checked','ON','CLICK ME');
    

    checkbox()は他とは論理的に関連付けられない分離されたチェックボックスを作成するために使われます。

    パラメータ:
  • 最初のパラメータは必須で、チェックボックスのための名前です (-name)。それはチェックボックスの隣に出力されるユーザが読むことができるラベルとしても使われます。
  • 2番目のパラメータ(-checked) はオプションで、デフォルトでチェックボックスがonとすることを指定します。 シノニムは、-selected と -onです。
  • 3番目のパラメータ(-value)はチェックされたときのチェックボックスの値を指定します。指定されなければ、"on"が想定されます。
  • 4番目のパラメータ(-label) はチェックボックスにつけられるユーザが読むことが出来るラベルです。指定されなければ、チェックボックスの名前が使われます。
  • チェックボックスの値は以下のようにして取り出すことが出来ます:

        $turned_on = $query->param('checkbox_name');
    

    JAVASCRIPTING: checkbox()は-onClick パラメータを理解します。さらに詳細な情報はcheckbox_group()をご覧下さい。


    ラジオボタン・グループの作成

       print $query->radio_group(-name=>'group_name',
                                 -values=>['eenie','meenie','minie'],
                                 -default=>'meenie',
                                 -linebreak=>'true',
                                 -labels=>\%labels);
    
            -または-
    
       print $query->radio_group('group_name',['eenie','meenie','minie'],
                                              'meenie','true',\%labels);
    
       HTML3-互換ブラウザのみ:
    
       print $query->radio_group(-name=>'group_name',
                                 -values=>['eenie','meenie','minie','moe'],
                                 -rows=2,-columns=>2);
    

    radio_group()は論理的に関連付けられたラジオボタンのセット(グループのメンバーの1つがオンになると、他はオフになります)を作成します。

    パラメータ:
  • 最初の引数はグループ名で必須です (-name)。
  • 2番目の引数(-values) はラジオボタンのための値のリストです。ページ上で表示される値とラベルはインデントされます。2番目の引数には配列リファレンスか、上記に示されたような無名配列、または"\@foo"のように名前付き配列をリファレンスにしたもの渡してください。
  • 3番目のパラメータ(-default) はオプションで、オンするデフォルトボタンの名前です。指定されなければ最初の要素がデフォルトになります。何もボタンが選択されていない状態で開始するために、"-"のような存在しないボタン名を指定することが出来ます。
  • 4番目のパラメータは(-linebreak) オプションで、ボタンの間に改行を入れ、垂直なリストを作成するために'true'に設定することが出来ます。
  • 5番目のパラメータ(-labels)はオプションで、ラジオボタンの値と表示のときに使われるユーザに見えるラベルとを関連付ける連想配列へのポインタです。与えられなければ、値そのものが表示されます。
  • (Netscapeのような)HTML3互換ブラウザ はさらにオプションのパラメータ、-rows-columnsを取ることが出来ます。これらのパラメータはradio_group()に、指定された行数、列数でフォーマットされたラジオボタンのグループが入ったHTML3互換のテーブルを返すようにします。もし望めば、 -columnsパラメータだけを与えることが出来ます;radio_groupは正しい行数をあなたに代って計算します。

    返されるテーブルに行と列のヘッダを入れるために、-rowheader-colheaderパラメータを使うことが出来ます。これらは両方とも使用するヘッダの配列へのポインタを受取ります。ヘッダは単なる飾りです。それらはラジオボタンの解析を理解しません--それらはまだ名前がついた1つのユニットです。

  • フォームが処理されるとき、選択されたラジオボタンは以下のようにして取り出すことが出来ます:

          $which_radio_button = $query->param('group_name');
    

    radio_group()により返される値は実際にはボタン要素の配列です。以下のようにしてそれらを取得し、テーブル、リストまたはその他の作成方法で使うことが出来ます:

        @h = $query->radio_group(-name=>'group_name',-values=>\@values);
        &use_in_creative_way(@h);
    

    (訳者注:サブミット・ボタンほうに紛れ込んでいましたが、本来はここでしょう)

    JAVASCRIPTING: radio_group()-onClick パラメータを理解します。さらなる詳細はcheckbox_groupをご覧下さい。


    サブミット・ボタンの作成

       print $query->submit(-name=>'button_name',
                            -value=>'value');
    
            -または-
    
       print $query->submit('button_name','value');
    

    submit()は問い合わせサブミット・ボタンを作成します。すべてのフォームはこれらのいずれかを持たなければなりません。

    パラメータ:
  • 最初の引数(-name) はオプションです。フォームにたくさんのサブミット・ボタンを持っていて、それらを区別したければ、名前を与えることが出来ます。 名前はユーザに見えるラベルとしても使われます。古いブラウザにはこれを正しく扱わず、ボタンからまったく送信しないものもあることに注意してください。
  • 2番目の引数 (-value) もオプションです。これはボタンに、問い合わせ文字列でスクリプトに渡される値を与えます。
  • それぞれに異なる値を使うことによりどのボタンが押されたかを見分けることが出来ます:

         $which_one = $query->param('button_name');
    

    JAVASCRIPTING: radio_group()-onClick パラメータを理解します。さらなる詳細はcheckbox_groupをご覧下さい。

    (訳者注:radio_groupはsubmitの間違いでしょう)


    リセット・ボタンの作成

       print $query->reset
    

    reset() reset()は"リセット"ボタンを作成します。必ずしもデフォルトではなく、最後にスクリプトが呼ばれたときからの値をそのフォームに再設定することに注意してください。

    これがPerlに組込まれているreset()とぶつかることに注意してください。元のreset関数を取得するにはCORE::reset()を使ってください。


    デフォルト・ボタンの作成

       print $query->defaults('button_label')
    

    defaults()は、呼び出されたとき、フォームを完全にデフォルトにリセットし、ユーザがそれまで行ったすべての変更を洗い流させるボタンを作成します。


    ヒドゥン・フィールドの作成

            print $query->hidden(-name=>'hidden_name',
                                 -default=>['value1','value2'...]);
    
                    -または-
    
            print $query->hidden('hidden_name','value1','value2'...);
    

    hidden()はユーザには見えないテキスト・フィールドを作成します。これはあるスクリプトの呼び出しから次へ状態変数情報を渡すのに便利です。

    パラメータ:
  • 最初の引数は必須で、このフィールドの名前を指定します (-name)。
  • 2番目の引数も必須で、その値を指定します (-default)。呼び出しの名前付きパラメータ形式では、1つの値またはリスト全体へのリファレンスを指定することが出来ます。
  • ヒドゥン・フィールドの値は以下のようにして取り出してください:

         $hidden_value = $query->param('hidden_name');
    

    他のすべてのフォーム要素と同じように、ヒドゥン・フィールドは"なかなか変わらない"であることに注意してください。スクリプトが一度呼び出された後に、何か他の値でヒドゥン・フィールドを置き換えたければ、手動でおこなう必要があります:

         $query->param('hidden_name','new','values','here');
    

    クリッカブル・イメージ・ボタンの作成

         print $query->image_button(-name=>'button_name',
                                    -src=>'/source/URL',
                                    -align=>'MIDDLE');      
    
            -または-
    
         print $query->image_button('button_name','/source/URL','MIDDLE');
    

    image_button()はクリッカブルなイメージを作成します。クリックされると、クリックの位置がスクリプトへ"bottun_name.x"と"button_name.y"として返されます。"button_name"のところはそれに指定した名前です。

    JAVASCRIPTING: image_buttonは-onClick パラメータを理解します。さらなる詳細はcheckbox_group()をご覧下さい。

    パラメータ:
  • 最初の引数(-name) は必須で、このフィールドの名前を指定します。
  • 2番目の引数(-src) も必須で、URLを指定します。
  • 3番目のオプション(-align, optional) はアラインメントのタイプで、TOP, BOTTOMまたはMIDDLEを指定することが出来ます。
  • このボタンの値は以下のようにして取り出してください:$x = $query->param('button_name.x'); $y = $query->param('button_name.y');


    JAVASCRIPTアクション・ボタンの作成

         print $query->button(-name=>'button_name',
                              -value=>'user visible label',
                              -onClick=>"do_something()");
    
            -または-
    
         print $query->button('button_name',"do_something()");
    

    button()はNetscape 2.0のJavaScriptと互換性のあるボタンを作成します。-onClick パラメータで示されるJavaScriptのコードが実行されます。Netscapeではないブラウザでは、このフォーム要素は多分表示すらされないでしょう。


    HTTPクッキー

    Netscapeブラウザ バージョン1.1以上とInternet Explorerのすべてのバージョンはブラウザ・セッションでの状態を保持することを助けるように設計された、いわゆる"クッキー"をサポートしています。CGI.pmはクッキーをサポートするさまざまなメソッドを持っています。

    クッキーは、CGI問い合わせ文字列の名前付きパラメータによく似た名前=値の組みです。CGIスクリプトは1つまたは複数のクッキーを作り、HTTPヘッダに入れてブラウザに送信します。ブラウザは特定のWebサーバに所属するクッキーのリストを保持し、その後の対話の間、CGIスクリプトに返します。

    必須の名前=値の組に加えて、各クッキーはさまざまなオプションの属性を持っています:

    1. 有効期限(expiration time)

      これはクッキーの有効期限を示す時刻/日付の文字列(特別なGMTフォーマットによる)です。ユーザがブラウザを終了させ、再起動したならば、この有効期限が来るまで、クッキーは保存され、スクリプトに返されます。有効期限が指定されなければ、クッキーはユーザがブラウザを終わらせるまで有効です。

    2. ドメイン(domain)

      これはクッキーが有効であるドメイン名の全体あるいは一部です。ブラウザはドメイン名の一部がマッチする、すべてのホストにクッキーを返します。例えば、ドメイン名に".capricorn.com"を指定すれば、ブラウザは"www.capricorn.com", "www2.capricorn.com", "feckless.capricorn.com"などのマシンのすべて実行されているWebサーバにクッキーを返します。".edu"のように最上位のドメインにマッチしようとすることを防ぐよう、ドメイン名は少なくとも2つのピリオドが入っていなければなりません、もしドメインが指定されなければ、ブラウザはクッキーが作成されたホストのサーバにだけクッキーを返します。

    3. パス(path)

      クッキークリプトのURLをチpath属性を与えるとブラウザは、クッキーを返す前にスェックします。例えば、パスを"/cgi-bin"と指定すれば、"/cgi-bin/tally.pl", "/そして"/cgi-bin/customer_service/complain.pl"のそれぞれのcgi-bin/order.pl", スクリプトには返されますが、"/cgi-private/site_admin.pl'"には返されません。デフォルトではパスは"/"で、これはクッキーはあなたのサイトのすべてのCGIスクリプトに送信されます。

    4. "安全"フラグ("secure" flag)

      もし"secure"属性が設定されれば、クッキーは、CGIリクエストがSSLのようなセキュアなチャンネルで発生された場合にのみ送信されます。.

    HTTPクッキーへのインタフェースは cookie() メソッドです:

        $cookie = $query->cookie(-name=>'sessionID',
                                 -value=>'xyzzy',
                                 -expires=>'+1h',
                                 -path=>'/cgi-bin/database',
                                 -domain=>'.capricorn.org',
                                 -secure=>1);
        print $query->header(-cookie=>$cookie);
    

    cookie() は新しいクッキーを作成します。そのパラメータには以下のものがあります:

    -name
    クッキーの名前(必須)。これにはどんな文字列でも指定できます。ブラウザはそのクッキー名を空白が入らない、英数字に限定しますが、CGI.pmは、背後でクッキーをエスケープ、アンエスケープすることによりこれらの制限を取り払います。
    -value
    クッキーの値。これにはすべてのスカラ値、配列リファレンス、さらに連想配列リファレンスさえも指定できます。例えば完全な連想配列をクッキーに以下のようにして格納することが出来ます:
            $cookie=$query->cookie(-name=>'family information',
                                   -value=>\%childrens_ages);
    
    -path
    オプションで、上記で説明したようにクッキーが有効になるパスの一部。
    -domain
    オプションで、上記で説明したようにクッキーが有効になるドメインの一部。
    -expires
    オプションで、このクッキーの有効期限。フォーマットはheader() メソッドについてのセクションで説明したのと同じ:
            "+1h"  今から1時間
    
    -secure
    trueに設定されれば、このクッキーは安全なSSLセッションでのみ使われます。

    cookie()によって作成されたクッキーは、header()メソッドによって返される文字列で、HTTPヘッダの中に入れられなければなりません:

            print $query->header(-cookie=>$my_cookie);
    

    複数のクッキーを作成するには、header()に配列リファレンスを指定してください:

            $cookie1 = $query->cookie(-name=>'riddle_name',
                                      -value=>"The Sphynx's Question");
            $cookie2 = $query->cookie(-name=>'answers',
                                      -value=>\%answers);
            print $query->header(-cookie=>[$cookie1,$cookie2]);
    

    クッキーを取り出すには、cookie()メソッドを-valueパラメータなしで呼び出すことによって名前で要求します:

            use CGI;
            $query = new CGI;
            %answers = $query->cookie(-name=>'answers');
            # $query->cookie('answers') will work too!
    

    クッキーとCGI名前空間は分かれています。もし'answers'という名前のパラメータと'answers'という名前のクッキーを持っていれば、param()とcookie()によって取り出される値はそれぞれ独立しています。しかしながら、CGIパラメータをクッキーにしたり、その反対も簡単です:

       # CGIパラメータをクッキーにする
       $c=$q->cookie(-name=>'answers',-value=>[$q->param('answers')]);
       # その反対
       $q->param(-name=>'answers',-value=>[$q->cookie('answers')]);
    

    クッキーをどのように効率よく使うかについてのいくつかのアイデアについては、例のスクリプトcookie.cgi をご覧下さい。


    フレームの利用

    CGI.pmスクリプトではHTML4フレーム機能を使って、たくさんのブラウザ・パネルとウィンドウに書き込むことができます。プログラム的に新しいフレームを定義するためには3つのテクニックがあります:

    1. <Frameset>ドキュメントの作成

      HTTPヘッダを出力した後、start_html()呼び出しを使って標準のHTMLドキュメントを作成する代りに、ページにフレームを定義する<FRAMESET>ドキュメントを作成します。各フレームのSRCとしてスクリプト(適切なパラメータをつけて)を指定します。

      CGI.pmには<FRAMESET>セクションを作成するのに特別なサポートはありません。しかしHTMLはとても簡単に書けます。詳細についてはネトスケープのホームページにあるフレームのドキュメントをご覧ください。

        http://home.netscape.com/assist/net_sites/frames.html
      
    2. HTTPヘッダでドキュメントの出力先を指定

      header()に-target を指定することが出来ます:

          print $q->header(-target=>'ResultsWindow');
      

      これはブラウザにスクリプトの出力を"ResultsWindow"という名前のフレームにロードするように伝えます。もしその名前のフレームがなければ、ブラウザは新しいウィンドウを立ち上げ、それにスクリプトのドキュメントをロードします。ターゲットに使うことが出来る特別な名前がたくさんあります。詳細についてはネットスケープのホームページにあるフレームのドキュメントをご覧ください。

    3. <FORM>タグでドキュメントの出力先を指定

      FORMタグそれ自身にロードするフレームを指定することが出来ます。CGI.pmでは以下のようになります:

          print $q->start_form(-target=>'ResultsWindow');
      

      フォームによりスクリプトが再び呼び出されると、その出力は"ResultsWindow"という名前のフレームにロードされます。それがまだなければ、新しいウィンドウが作成されます。

    examplesディレクトリにあるスクリプト"frameset.cgi"は、フォームとレスポンスが隣り合ったフレームに存在するページを作成する1つの方法を示しています。


    カスケーディング・スタイル・シートの限定サポート

    CGI.pm はHTML3のカスケーディング・スタイル・シート(css)を限定付きでサポートします。スタイルシートをドキュメントに組込むためには、start_html()メソッドに-style パラメータを渡します。このパラメータの値にはスカラ、この場合は直接<STYLE>セクションに組込まれます、あるいはハッシュ・リファレンスを指定することが出来ます。後者の場合は、1つあるいは複数の-src または -codeを持ったハッシュを指定しなければいけません。-srcは完全に定義されたスタイルシートを見つけることが出来るURLを示します。-codeは<STYLE>セクションに組込まれるスカラ値を示します。-codeでのスタイルの定義は、-srcでの同じ名前のもので上書きされます。これゆえに名前が"cascading"(滝のように落ちる)なのです。

    -styleによって示されるハッシュに、オプションの-type を加えることによりスタイルシートの種類を指定することも出来ます。もし指定されなければ、そのスタイルはデフォルトの'text/css'です。

    ドキュメントの本体(Body)でスタイルを参照するには、HTML要素に-class を加えます:

        print h1({-class=>'Fancy'},'Welcome to the Party');
    

    もしくは、その場で-styleパラメータでスタイルを定義します:

        print h1({-style=>'Color: red;'},'Welcome to Hell');
    

    テキストのセクションにスタイルを適用するため、新しいspan()を使うことも出来ます:

        print span({-style=>'Color: red;'},
                   h1('Welcome to Hell'),
                   "Where did that handbasket get to?"
                   );
    

    span()メソッドを使えるようにするためには":html3"をインポートしなければいけないことに注意してください。CSS使用の簡単で汚い例を以下に示します。さらなる詳細はhttp://www.w3.org/pub/WWW/TR/Wd-css-1.html にあるCSSの仕様をご覧下さい。

        use CGI qw/:standard :html3/;
    
        #ここはページに直接組込まれるスタイルシートです
        $newStyle=<<END;
        <!-- 
        P.Tip {
            margin-right: 50pt;
            margin-left: 50pt;
            color: red;
        }
        P.Alert {
            font-size: 30pt;
            font-family: sans-serif;
          color: red;
        }
        -->
        END
        print header();
        print start_html( -title=>'CGI with Style',
                          -style=>{-src=>'http://www.capricorn.com/style/st1.css',
                                   -code=>$newStyle}
                         );
        print h1('CGI with Style'),
              p({-class=>'Tip'},
                "Better read the cascading style sheet spec before playing with this!"),
              span({-style=>'color: magenta'},
                   "Look Mom, no hands!",
                   p(),
                   "Whooo wee!"
                   );
        print end_html;
    

    ドキュメントに複数のスタイルシートを組み込むためには-styleに配列リファレンスを渡してください。


    デバッグ方法

    コマンドラインからスクリプトを実行するか、perlデバッガのなかで実行するならば、キーワードのリストやパラメータ=値の組をコマンド行や標準入力からスクリプトに渡すことが出来ます(環境変数からスクリプトに読み込むような仕組みについて心配する必要はありません)。キーワードを以下のようにして渡すことが出来ます:

        your_script.pl keyword1 keyword2 keyword3
    

    あるいは:

       your_script.pl keyword1+keyword2+keyword3
    

    あるいは:

        your_script.pl name1=value1 name2=value2
    

    あるいは:

        your_script.pl name1=value1&name2=value2
    

    この機能をオフにするには、-no_debugプラグマを使ってください。

    POSTメソッドをテストするために、-debugプラグマでフルのデバッグを可能にすることができます。これは改行で区切った名前=値の組み合わせを標準入力からスクリプトに食わせることができます。

    デバッグのとき、よく知っているシェルのマナーで、文字をエスケープするためにクォートとバックスラッシュを使うことが出来ます。パラメータ=値の組で、空白や他の変わった文字を置かせるためには以下のようにします:

       your_script.pl "name1='I am a long value'" "name2=two\ words"
    

    すべての名前/値の組み合わせをダンプ

    Dump()メソッドはすべての問い合わせの名前/組が入った、ネストしたリストとしてうまくフォーマットされた文字列を作成します。こればデバッグの目的には有効です:

        print $query->Dump
    

    これは以下のようなものを作成します:

        <UL>
        <LI>name1
            <UL>
            <LI>value1
            <LI>value2
            </UL>
        <LI>name2
            <UL>
            <LI>value1
            </UL>
        </UL>
    

    ショートカットとして、完全なCGIオブジェクトを文字列にいれることが出来ます。そしてそれは上記に示されるきれいなHTMLダンプで置きかえられます:

        $query=new CGI;
        print "<H2>Current Values</H2> $query\n";
    

    環境変数の取り出し

    いくつかのより便利な環境変数がこのインターフェースを通して取り出すことが出来ます。メソッドを以下に示します:

    Accept()
    リモートのブラウザが受取るMIMEタイプのリストを返します。 $query->Accept('text/html')のように、もしこのメソッドにMIMEタイプに対応する1つの引数を渡せば、このタイプについてのブラウザの優先順位に対応する0.0(欲しくありません)から1.0までの浮動小数点値を返します。ブラウザの受取リストでのグロブ・タイプ(例えば text/*)は正確に扱われます。

    Perlのaccept()関数とぶつかることを避けるために、2.43と2.44の間で先頭文字が大文字に変更されたことに注意してください。

    raw_cookie()
    Netscapeブラウザ バージョン1.1以上とInternet ExplorerのすべてのバージョンによるHTTP拡張である、HTTP_COOKIE変数を返します。クッキーは特別なフォーマットを持っており、このメソッドは単にそのままの形式を返します(?クッキーのタネ)。調理されたクッキーを設定し、取得する方法については、cookie()をご覧下さい。

    パラメータなしで呼ばれると、raw_cookie()はパックされたクッキー構造体を返します。";"の文字並びで分割(split)することにより、ここのクッキーに分けることが出来ます。クッキーの名前をつけて呼び出すと、クッキーのアンエスケープされた形式を取り出します。名前を取得するために、通常のcookie()メソッドを使ってリ、CGI::Cookieモジュールからのraw_fetchメソッドを使うことが出来ます。

    user_agent()
    HTTP_USER_AGENT 変数を返します。このメソッドに1つの引数を与えると、それにパターンマッチを試み、 $query->user_agent(netscape); のようなことをおこなうことを可能にします。
    path_info()
    スクリプトからの追加パス情報を返します。例えば /cgi-bin/your_script/additional/stuffを取り出すことは、$query->path_info()は結果として"addtional/stuff"を返します。

    注意:Microsoft Internet Information Server は追加のパス情報の見方でおかしくなっています。Perl DLLライブラリを使うと、IISサーバはPerlスクリプトとして追加パス情報を実行しようとします。もし通常のファイル関連マッピングを使えば、パス情報は環境変数に表れますが、正しくありません。これをおこなう一番よいことは、IISで使用するようなCGIでは追加パス情報を使うのを避けることです。

    path_translated()
    path_info()と同様、しかし追加パス情報を物理パス情報に変換します。例えば"/usr/local/etc/httpd/htdocs/addtional/stuff"。

    変換されたパスについてもMicrosoft IISはイカレています。

    remote_host()
    リモート・ホスト名または、もし前者が使えなければIPアドレスのどちらかを返します。
    script_name()
    自分を参照するスクリプトのために、URLの一部としてスクリプト名を返します。
    referer()
    ブラウザがスクリプトを取り出す前に見ていたページのURLを返します。すべてのブラウザに利用できるわけではありません。
    auth_type ()
    もしあれば、このスクリプトのために使われた、authorization/verification (認証/検証)方法を返します。
    server_name ()
    サーバの名前、通常はマシンのホスト名を返します。
    virtual_host ()
    バーチャル・ホストを使っているとき、ブラウザがコンタクトしようとしたホストの名前を返します。
    server_software ()
    サーバ・ソフトウェアとバージョン番号を返します。
    remote_user ()
    このスクリプトが保護されていれば、ユーザ検証に使われたauthorization/verification 名を返します。
    user_name ()
    さまざまな異なる技術を使ってリモートユーザの名前を取得しようとします。これはMosaicのような古いブラウザでのみ機能します。新しいブラウザはプライバシーの理由からユーザ名を報告しません!
    request_method()
    スクリプトにアクセスするために使われたメソッドを返します。通常は'POST'、'GET'または'HEAD'のどれか1つです。
    content_type()
    POSTで送信されてきたデータのcontent_typeを返します。一般にはmultipart/form-data または application/x-www-form-urlencodedです。
    http()
    引数なしで呼ばれると、それぞれリクエストでの似たようなHTTPヘッダ・フィールドに対応する、HTTP_USER_AGENT、HTTP_ACCEPT_LANGUAGE、そしてHTTP_ACCEPT_CHARSETのようなものが入った環境変数のリストを返します。HTTPヘッダ・フィールドの名前付きで呼ばれると、その値を返します。大文字/小文字、アンダースコアの代わりにハイフンを使うことは区別されません。

    例えば、この3つの例はすべて同値です:

       $requested_language = $q->http('Accept-language');
       $requested_language = $q->http('Accept_language');
       $requested_language = $q->http('HTTP_ACCEPT_LANGUAGE');
    
    https()
    http()と同じ。しかしSSLプロトコルが有効なときに現れる、HTTPS環境変数を扱います。SSLがオンになっているかどうかを判定するためにも使うことができます。

    NPHスクリプトの使用法

    NPH, または"解析されないヘッダ"("no-parsed-header")、では、完全なHTTPヘッダを直接ブラウザに送信することにより、スクリプトはサーバを完全にバイパスします。これはパフォーマンスの面で少し利点があります。しかしほとんどは、サーバ・プッシュやPICSヘッダのような、サーバによって直接にはサポートされていないHTTP拡張の利点を得るために使われます。

    CGIスクリプトをNPHとして示すために、さまざまな約束が使われます。多くのUnixサーバはスクリプトの名前の始まりに接頭辞"nph-"があるかを見ます。これに対して、Macintosh WebSTARサーバと MicrosoftのInternet Information Serverは、スクリプト出力の先頭行をチェックすることによりNPHスクリプトであるかを判定しようとします。

    CGI.pmは特別はNPHモードでNPHスクリプトをサポートします。このモードでは、CGI.pmはheader()やredirect()メソッドが呼ばれると、必要な特殊なヘッダ情報を出力します。

    Microsoft Internet Information Server はNPHを必要とします。version 2.30では、CGI.pmはIISの元で実行されたとき自動的に検知し、自分自身でこのモードにします。手動でこのモードにする必要はありません。しかしそうしたからといって、何も問題はありません。

    CGI.pmをNPHモードにするためにはいくつかの方法があります:

    useステートメントで
    スクリプトにインポートされるシンボルのリストに単に"-nph"プラグマを追加してください:
          use CGI qw(:standard -nph)
    
    nph()メソッドの呼出し
    CGI.pmをプログラムで使った後のどこかの時点で、非0のパラメータでnph() を呼び出してください。
          CGI->nph(1)
    
    header() とredirect() ステートメントで-nph パラメータを使う:
          print $q->header(-nph=>1);
    

    サーバー・プッシュ

    CGI.pmは、サーバ・プッシュを実装するために必要な種類であるマルチパート・ドキュメントを作成するために3つの簡単な関数を提供しています。これらの関数はありがたいことに Ed Jordan <ed@fidalgo.net>によって提供されました。これらを名前空間にインポートするためには、":push"セットをインポートしなければいけません。またスクリプトをNPHモードとし、バッファリングの問題を避けるために$|を1に設定したほうがよいでしょう。

    これはサーバ・プッシュをデモンストレーションする簡単なスクリプトです:

      #!/usr/local/bin/perl
      use CGI qw/:push -nph/;
      $| = 1;
      print multipart_init(-boundary=>'----------------here we go!');
      while (1) {
          print multipart_start(-type=>'text/plain'),
                "The current time is ",scalar(localtime),"\n",
                multipart_end;
          sleep 1;
      }
    

    このスクリプトはmultipart_init()を呼ぶことによってサーバ・プッシュを初期化しています。そしてmultipart_start(),を呼ぶことによって新しいマルチパート・セクションを始め、現在のローカル・タイムを出力し、multipart_end()でマルチパート・セクションを終わらせているる無限ループに入ります。そして1秒スリープした後、再び開始します。

    multipart_init()
      multipart_init(-boundary=>$boundary);
    

    マルチパート・システムを初期化します。-boundary 引数はドキュメントの部分を分割するために使われるMIMEバウンダリ文字列を指定します。指定されなければ、CGI.pmはあなたに代わって合理的なバウンダリを選択します。

    multipart_start()
      multipart_start(-type=>$type)
    

    指定されたMIMEタイプを使ってマルチパート・ドキュメントの新しい部分を開始します。指定されなければ、text/htmlが想定されます。

    multipart_end()
      multipart_end()
    

    部分(part)を終わらせます。multipart_start()を呼ぶ毎にmultpart_end()を呼ぶ事を忘れては行けません。

    サーバ・プッシュ・アプリケーションに興味のあるユーザはCGI::Pushモジュールも見るべきです。


    サービス不能(DoS)攻撃の回避

    CGI.pmでの潜在的な問題は、デフォルトではどんなに大きくてもPOSTされたフォームを処理しようとすることです。ずるがしこいハッカーは数メガバイトの巨大なPOSTをCGIスクリプトに送信することにより、あたなのサイトを攻撃することが出来ます。CGI.pmはPOST全体を変数に読み込もうとし、メモリがなくなるまでその大きさは巨大に成長します。スクリプトがメモリを占有しようとする間、システムは劇的に遅くなるかもしれません。これがサービス不能(DoS)攻撃の形です。

    他の可能な攻撃はリモードユーザがCGI.pmに巨大なファイルのアップロードを受取ることを強要することです。CGI.pmは、例えあなたのスクリプトがアップロードされるファイルを受けることを予想していなくても、アップロードを受けつけ、それを一時ディレクトリに格納しようとします。CGI.pmはそれが終わったとき、自動的にファイルを削除します、しかしその間にリモートユーザがサーバのディスク空間をいっぱいにしてしまうかも知れません。他の問題を起こしながら。

    サービス・アタックの拒否を避ける一番よい方法は、CGIスクリプトが使うことができるメモリ量、CPU時間、ディスク容量を制限することです。いつくかのWebサーバはこれを実現する組込み機能を持っています。他の場合、シェルのlimit またはulimitをCGIの資源使用に上限を設定ために使うことが出来ます。

    CGI.pmはサービス・アタックの拒否に対するいくかの簡単な組込まれた保護も持っていますが、使えるようになる前に活性化させなければなりません。これらはCGI名前空間での2つのグローバル変数の形を取ります:

    $CGI::POST_MAX
    負でない整数が設定されると、この変数はPOSTされるサイズの上限をバイト数で、設定します。CGI.pmは上限よりも大きいPOSTを検知すると、エラーメッセージとともにすぐにexitします。この値は通常のPOSTとマルチパートPOSTの両方に影響を与えます。つまりファイル・アップロードの最大の大きさも制限するということです。これは、1メガバイトのように合理的な高い値を設定しなければいけません。
    $CGI::DISABLE_UPLOADS
    非0の値が設定されると、これはファイルのアップロードを完全に不可能にします。他のフォームの値は通常通り機能します。

    これらの変数を2つの方法どちらかで使うことが出来ます:

    1. スクリプト毎に

      "use"ステートメントのすぐ後に、スクリプトの先頭でその変数を設定します:

          use CGI qw/:standard/;
          use CGI::Carp 'fatalsToBrowser';
          $CGI::POST_MAX=1024 * 100;  # 最大 100K POST
          $CGI::DISABLE_UPLOADS = 1;  # アップロードなし
      
    2. すべてのスクリプトでグローバルに

      CGI.pmを開き、$POST_MAXと$DISABLE_UPLOADSのための定義を見つけ、それを望んでいる値に設定します。ファイルの先頭の近く、initialize_globals()という名前のサブルーチンの中で見つけるでしょう。

    $POST_MAXバイトよりも大きなPOSTを送信しようとするとparam()に空のCGIパラメータを返させます。このイベントは、CGIオブジェクトを作成した後もしくはもしくは関数指向イ