=encoding euc-jp =head1 名前 CGI - 簡単なCGI(Common Gateway Interface)クラス =head1 概要 # 画面一杯のフォームを作成し、その値をエコーバックする # 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; } =head1 要約 この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/ =head1 説明 =head2 プログラミング・スタイル CGI.pmでは2つのプログラミング・スタイル、オブジェクト指向スタイルと 関数指向スタイルがあります。オブジェクト指向スタイルでは、1つまたは 複数のCGIオブジェクトを作成し、ページのさまなざな要素を作成するために オブジェクト・メソッドを使います。各オブジェクトはサーバーによって スクリプトに渡された名前付きパラメータのリストが出発点となります。 オブジェクトを変更したり、ファイルやデータベースに格納し、それを元に 戻すことが出来ます。というのも各オブジェクトはCGIスクリプトの "状態"(state)に対応しており、各オブジェクトのパラメータ・リストは、 その他のものとは独立しているため、スクリプトの状態を保存し後から 取り出すこともできるのです。 以下にオブジェクト指向スタイルを使って、簡単な"Hello World"HTMLページを どのように作成するかの例を示します: #!/usr/local/bin/perl -w 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での関数指向プログラミングについての重要な情報は「関数のインポート方法」を ご覧下さい。 =head2 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('some','contents');

some contents

h1({-align=>left});

h1({-align=>left},'contents');

contents

HTMLタグについては後で詳しく記述します。 CGIを使い始めたばかりの人の多くが、HTMLタグ属性を囲む曲括弧を必要とする HTMLショートカットの呼び出し方と、曲括弧無しに属性の生成を管理する他の ルーチンの呼び出し方との違いに惑わされます。混乱しないで下さい。便宜上、 曲括弧はHTMLを除くすべてでオプションです。もし好きであれば、名前付き 引数を取る全てのルーチンも呼び出すときに曲括弧を使うことが出来ます。 例えば: print $q->header( {-type=>'image/gif',-expires=>'+3d'} ); B<-w>スイッチを使うと、いくつかのCGI.pm引数はPerl組込関数と名前が ぶつかっていることを警告されるでしょう。これらのほとんどは、 複数の値を持つメニュー(multi-valued menu)、ラジオボタン(radio button)、 クラスター(cluster)などを作成するために使われる-values引数です。 この警告を回避するためには、いくつかの選択肢があります: =over 4 =item 1. もし他の名前が使えれば、引数に他の名前を使う。 例えば-valueは-valuesのための別名です。 =item 2. 先頭を大文字化する。例. -Values =item 3. 引数名の周りをクォートで囲む。 例. '-values' =back 多くのルーチンが理解できない名前付き引数についても、なんらかの有効なことを 行います。例えば、名前付きの引数として与えることにより標準ではない 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の"標準"に迅速に追いかけることを可能にします。 =head2 新しい問い合わせオブジェクトの作成(オブジェクト指向スタイル): $query = new CGI; これは(POSTとGETメソッドの両方からの)入力を解析し、 $queryと呼ばれるperl5オブジェクトに格納します。 =head2 入力ファイルからの新しい問い合わせオブジェクトの作成 $query = new CGI(INPUTFILE); もしファイル・ハンドルをnew()メソッドに与えると、ファイル(またはSTDINでもなんでも) からパラメータを読み込みます。デバッグ中、ファイルには以下に説明する 形式ならば、何にでもすることができます(つまり改行で区切られたタグ=値の組が機能します)。 便利なことに、このファイルのタイプはsave()メソッドにより作成されます。 複数のレコードを保存し、元に戻すことが出来ます。 Perl純粋主義者はこの文法がファイル・ハンドルを、ファイルハンドル・グロブさえも 受取ることを知って喜ぶでしょう、これはファイルハンドルを渡す"公式の"方法です: $query = new CGI(\*STDIN); CGIオブジェクトをFileHandleまたはIO::Fileオブジェクトで初期化することも 出来ます。 関数指向インターフェースを使っていて、CGI状態をファイル・ハンドルで 初期化したければ、Bでおこないます。これはデフォルトの 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({}); =head2 問い合わせからのキーワードのリストの取り出し: @keywords = $query->keywords 検索の結果としてスクリプトが呼び出されれば、解析されたキーワードは keywords()メソッドを使って配列として取得することが出来ます。 =head2 スクリプトの渡された全てのパラメータの名前の取り出し: @names = $query->param パラメータ付きでスクリプトが呼び出されると(例えば"name1=value1&name2=value2&name3=value3")、 param()メソッドはパラメータ名をリストで返します。もしスクリプトがスクリプトとして 呼び出され、アンパサンドのない文字列が入っていれば(例えば、"value1+value2+value3")、 "+"で区切られたキーワードが入った"keywords"という名前の1つのパラメータになります。 注意:バージョン1.5では、パラメータ名の配列はブラウザにより実行されたのと 同じ順番でした。通常、この順序はパラメータがフォームで定義された順と 同じです(しかしながら仕様には入っていないため保証はされません。) =head2 1つの名前つきパラメータの値を取り出す: @values = $query->param('foo'); -または- $value = $query->param('foo'); 名前付きパラメータの値を取り出すためにparam()メソッドに1つの引数を 渡してください。もしそのパラメータが複数の値を持っていれば (例えばスクローリング・リスト(scrolling list)での複数の選択から)、 配列で受取るようにすることが出来ます。そうでなければ、このメソッドは 1つの値を返します。 もし値が問い合わせ文字列で与えられなければ、つまり問い合わせで "name1=&name2=""または"name1&name2"であれば、空文字列を返します。 これは2.63での新機能です。 =head2 名前つきパラメータへの値の設定: $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'); =head2 名前つきパラメータに値を追加する: $query->append(-name=>'foo',-values=>['yet','more','values']); これは値または値のリストを名前付きパラメータに追加します。 既にあれば、その値はパラメータの最後に追加されます。そうでなければ パラメータが作成されます。このメソッドは名前付き引数呼び出し書式しか 理解しないことに注意してください。 =head2 すべてのパラメータの名前空間へのインポート: $query->import_names('R'); これは一連の変数を'R'名前空間に作成します。例えば$R::foo、@R:fooのように。 キーワード・リストでは、変数@R:keywordがあります。名前空間が指定されなければ、 この引数は'Q'を想定します。警告:'main'には何もインポートしないこと。 それはセキュリティ上、大きな危険性があります!!! 古いバージョンでは、このメソッドはBと呼ばれていました。 バージョン2.20では、組込PerlモジュールB演算子とぶつかることを 避けるため、この名前は完全に削除されました。 =head2 パラメータを完全に削除する: $query->delete('foo','bar','baz'); これは完全にパラメータをクリアします。それはスクリプト呼び出しの間で、 渡されたものが欲しくないパラメータをリセットするのに便利なこともあります。 関数呼び出しインターフェースを使っているのであれば、Perlの組込み演算子delete との衝突を避けるため、代りに"Delete()"を使ってください。 =head2 すべてのパラメータを削除する: $query->delete_all(); これはCGIオブジェクトを完全にクリアします。これはフォームを作成するときに、 すべてのデフォルトが取られることを保証するために便利です。 関数呼び出しインターフェースを使っているならば、代りにDelete_all()を使って ください。 =head2 パラメータリストへの直接アクセス: $q->param_fetch('address')->[1] = '1313 Mockingbird Lane'; unshift @{$q->param_fetch(-name=>'address')},'George Munster'; パラメータ・リストへアクセスする必要があれば、これまでのメソッドでは カバーされていません。その名前でBを呼び出すことにより、 それへの直接のリファレンスを取得することが出来ます。これは名前付き パラメータへの配列リファレンスを返します。それは好きなように扱うことが 出来ます。 B<-name>を使って、名前付き引数スタイルを使うことも出来ます。 =head2 パラメータリストのハッシュでの取り出し: $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との互換性についてのセクションも ご覧下さい) =head2 スクリプトの状態をファイルに保存する: $query->save(FILEHANDLE) これはフォームの現在の状態を指定されたファイルハンドルに 書き込みます。new()メソッドにファイルハンドルを与えることにより 読み戻すことが出来ます。ファイルハンドルは、ファイル、パイプ、 その他何にでもにすることが出来ることに注意してください! 保存されるファイルの形式は以下の通りです: NAME1=VALUE1 NAME1=VALUE1' NAME2=VALUE2 NAME3=VALUE3 = 名前と値の両方がURLエスケープされます。複数の値を持つCGIパラメータは 名前を繰り返すことにより表すことができます。セッション・レコードは single=symbolによって範囲を決められます。何回もBを呼ぶことにより、 複数のレコードを書き出し、読み戻すことが出来ます。追記(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)からこの関数を使いたいのであれば、エクスポートされる このメソッドの名前はBです。 =head2 CGIエラーの取り出し ユーザ入力を処理して切る間、特にアップロードされたファイルを処理している 間にエラーが発生することがあります。これらのエラーが発生したとき、CGIは 処理を止め、空のパラメータリストを返します。エラーの存在とその性質を I関数を使って調べることが出来ます。エラーメッセージは 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; } 関数指向インターフェース(次のセクションをご覧下さい)を使うとき、 エラーは最初にIを呼んだときにだけ発生します。 これに備えてください! =head2 関数指向インターフェースの使い方 関数指向インタフェースを使うためには、どの CGI.pmルーチンまたは 関数群をスクリプトの名前空間にインポートするかを指定しなければいけません。 このインポートに関連して少しオーバーヘッドがありますが、大したことはありません。 use CGI <メソッドのリスト>; リストに入れられたメソッドは現在のパッケージにインポートされます; CGIオブジェクトを最初に作成することなく直接呼び出すことが出来ます。 この例ではどのようにBとBメソッドをインポートし、それらを 直接使うかを示しています: use CGI 'param','header'; print header('text/plain'); $zipcode = param('zipcode'); さらに多くの場合、名前でグループを参照することにより一般的な関数の組を インポートします。すべての関数の組の前には":html3"(HTML3標準で定義されたタグ用) のように、前に":"がつきます。 以下にインポートできる関数の組のリストを示します: =over 4 =item B<:cgi> B, Bのような、CGIを扱うすべてのメソッドをインポート します。 =item B<:form> Bのような、フォームを作成するメソッドをインポートします。 =item B<:html2> HTML 2.0 標準要素を作成するすべてのメソッドをインポートします。 =item B<:html3> HTML 3.0 標準要素を作成するすべてのメソッドをインポートします。 (、 そしてのような) =item B<:html4> HTML 4 標準要素を作成するすべてのメソッドをインポートします。 (, そして のような) =item B<:netscape> Netscape特有のHTML拡張を作成するすべてのメソッドをインポートします。 =item B<:html> すべてのHTML作成ショートカットをインポートします(つまり'html2' + 'html3' + 'netscape')... =item B<:standard> "標準"の機能をインポートします。, 'html2', 'html3', 'html4', 'form' そして 'cgi'。 =item B<:all> 利用可能なすべてのメソッドをインポートします。全体のリストはCGI.pmの コードをご覧下さい。%EXPORT_TAGSという変数が定義されています。 =back CGI.pmの一部ではない関数名をインポートすると、モジュールはそれを 新しいHTMLタグとして扱い、適切なサブルーチンを作成します。そこで 他のHTMLタグと同じように使うことが出来ます。これは急速に発展する HTMLの"標準"を提供するためです。例えばMicrosoftはという 新しいタグを発表しています(これはマシンをリブートするまで、 ユーザのデスクトップを回転する斜線でいっぱいにします)。新しい バージョンのCGI.pmを待つ必要はありません、それをすぐに使って みてください: use CGI qw/:standard :html3 gradient/; print gradient({-start=>'red',-end=>'blue'}); 実行スピードの点から、CGI.pmはロード・シンボルを指定するための 標準のLの書式を使わないことに注意してください。これは将来 変更されるかもしれません。 もし状態管理CGI、またはフォーム作成メソッドのいずれかをインポート すると、あることを要求するメソッドのいずれかを最初に使ったときに、 デフォルトのCGIオブジェクトが自動的に作成され初期化されます。 これにはB, B, B などが含まれます。 (直接CGIオブジェクトにアクセスする必要があれば、 グローバル変数B<$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; =head2 プラグマ 関数セットに加えて、多くのプラグマをインポートすることができます。 プラグマの前には常にハイフンがつき、多くの方法でCGI.pm関数の動きを 変更します。プラグマ、関数セットそして個々の関数はすべて同じuse()行で インポートすることができます。例えば、以下のuseステートメントは標準の 関数セットをインポートし、デバッグ・モードを不可能にします (プラグマ -no_debug): use CGI qw/:standard -debug/; プラグマの現在の一覧を以下に示します: =over 4 =item -any Iを使うとき、問い合わせオブジェクトが理解しない 全てのメソッドはHTMLタグとして解釈されます。これにより次の I<アドホックな>NetscapeとMicrosoft特有のHTML拡張をサポートする ことが出来ます。これは新しく、まだサポートされていないタグを 自由に使わせてくれます: use CGI qw(-any); $q=new CGI; print $q->gradient({speed=>'fast',start=>'red',end=>'blue'}); anyを使うと打ち間違えたどんなメソッド名も HTMLタグとして解釈されるので、使うときには注意するか、まったく 使わないかのどちらかにしてください。 =item -compile これは指定されたオートロードされるメソッドが後に延期されるのではなく、 先にコンパイルされます。これはFastCGIやmod_perlなどのMalcom Beattieの Perlコンパイラにバリバリ食わせるようになっているような状況の下で、 長時間、実行されるスクリプトには有効です。使おうとしているメソッド あるいはメソッド・ファミリと結合して使ってください。 use CGI qw(-compile :standard :html3); あるいは以下のようにさえも use CGI qw(-compile :all); このようにして-compile プラグマを使うことは、コンパイルされた 関数が現在の名前空間にインポートされる効果を常に持つことに注意して ください。インポートすることなしにコンパイルしたければ、代りに compile()メソッドを使ってください(下記をご覧下さい): use CGI(); CGI->compile(); これはあなたはstartupスクリプトで全てのCGIルーチンを予めコンパイル しておき、各mod_perlスクリプトで個別に関数をインポートしたいかも しれないmod_perl環境では特に便利です。 =item -nosticky これはCGI.pmにヒドゥン・フィールド .submit と .cgifieldsを 作らせません。 GETメソッドでの問い合わせ文字列で ヒドゥン・フィールドを持ちたくないときに便利です。例えば、 この方法で作られた検索スクリプトはブックマークに適した、 検索パラメータを持ったurlになります。 =item -no_undef_params CGI.pmにパラメータリストでの未定義のパラメータを入れさせないようにします。 =item -no_xhtml デフォルトでは、CGI.pm バージョン2.69以降はXHTML (http://www.w3.org/TR/xhtml1/)を出力します。-no_xhtmlプラグマは、 この機能を止めます。この機能について Michalis Kabrianis に感謝します。 =item -nph これはCGI.pmにNPH(解析されないヘッダno parsed header)スクリプトに 適したヘッダを作成させます。サーバにそのスクリプトがNPHであると 告げるのと同じように他のことをする必要があるかも知れません。 NPHスクリプトについては下記をご覧下さい。 =item -newstyle_urls CGIパラメータ問い合わせ文字列の名前=値の組を、アンパサンドではなく セミコロンで分割します。例えば: ?name=fred;age=24;favorite_color=3 セミコロン区切りの問い合わせ文字列は常に受取られますが、 -newstyle_urls プラグマが指定されなければ、self_url()やquery_string()では出力されません。 これはバージョン2.64でデフォルトになりました。 =item -oldstyle_urls CGIパラメータ問い合わせ文字列の名前=値の組を、セミコロンではなく アンパサンドで分割します。これはもはやデフォルトではありません。 =item -autoload プログラム内の理解されないすべての関数が可能な評価のためにCGI.pmが 参照されるようautoloaderをオーバーライドします。これにより、それらを シンボル・テーブルに加えることなく、すべてのCGI.pm関数を使うことが出来ます。 これはメモリ消費を心配するmod_perlユーザに関連します。 I<警告:> I<-autoload>が有効なとき"詩的モード(poetry mode)"(括弧のない関数)を 使うことは出来ません。I
ではなくIを使うか、Iの ようなものをスクリプトの先頭に加えてください。 =item -no_debug これはコマンド行処理機能をオフにします。HTMLを作成するためCGI.pmをコマンド行から 実行したいけれども、標準入力やコマンド行からのリクエストCGIパラメータを解析したく ないのであれば、このプラグマを使ってください: use CGI qw(-no_debug :standard); =item -debug これはコマンド行処理機能をオンにします。コマンド行処理からCGI引数を 読み込むことに加えて、CGI.pmは一旦停止し、STDINから引数を読み込もうとして、 "(offline mode: enter name=value pairs on standard input)"という メッセージを出します。   さらなる詳細は「デバッグ」セクションをご覧ください。 =item -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. それぞれの場所はそれがディレクトリであるか、書きこみ可能かをチェックされます。 そうでなければアルゴリズムは次の選択を試してみます。 =back =head2 HTMLタグ関数のインポートのための特別な形式 メソッドの多くがHTMLを作成します。下記で説明するように、 タグ関数は自動的に開始と終了の両方のタグを自動的に作成します。 例えば: print h1('Level 1 Header'); は 以下のものを作成します。

Level 1 Header

ときには開始と終了タグを自分自身で作成したいときがあるでしょう。 この場合、以下のようにstart_I<タグ名>とend_I<タグ名>の形式を 使うことができます: print start_h1,'Level 1 Header',end_h1; いくつかの例外がありますが(下記で説明)、start_I<タグ名>とend_I<タグ名>関数は Iしたときに自動的に作成されません。しかし、その名前の前に アスタリスクを置くか、あるいは代わりに"start_I<タグ名>"や"end_I<タグ名>"を インポート・リストに要求することによって、I関数を作成したいタグを 指定することができます。 例: use CGI qw/:standard *table start_ul/; この例では、標準の関数に加えて以下の関数が作成されます: =over 4 =item 1. start_table() (
タグを作成) =item 2. end_table() (
タグを作成) =item 3. start_ul() (
    タグを作成) =item 4. end_ul() (
タグを作成) =back =head1 動的なドキュメント作成 CGI.pmの関数ほとんどは実行中にドキュメントを作成することを扱います。 一般的にはまずHTTPヘッダを作成し、その後にドキュメントそのものが続きます。 CGI.pmはHTMLを作成するのと同じくらい、多くのさまざまなHTTPヘッダを 作成するための関数を提供します!GIFイメージの作成についてはGD.pm モジュールをご覧ください。 これらの関数のそれぞれはHTMLやHTTPの一部を作成します。それらは 直接出力できるので、ブラウザ・ウィンドウに表示したり、文字列を 追加したり、後で使うようにファイルに保存したりといったことができます。 =head2 標準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メソッドへ引数を渡すための名前付き引数スタイルを示しています。 理解されるパラメータはB<-type>, B<-status>, B<-expires>, そしてB<-cookie>です。 他の名前がついたパラメータはすべて、最初のハイフンを落とされて、 ヘッダ・フィールドに変えられます、あなたが望むすべてのHTTPヘッダを指定する ことが可能です。内部のアンダースコアはハイフンに変換されます: print $query->header(-Content_length=>3002); ほとんどのブラウザはCGIスクリプトからの出力をキャッシュしません。 スクリプトが新たに呼び出されるたびに、ブラウザはページをリロードします。 この動きはB<-expires>で変更することができます。このパラメータで絶対または相対の 有効期間を指定すると、いくつかのブラウザとプロキシー・サーバは指定された有効期限まで、 そのスクリプトの出力をキャッシュします。以下の形式はすべて-expiresフィールドに 対して適切です: +30s 今から30秒 +10m 今から10分 +1h 今から1時間 -1d 昨日(つまり、できるだけ早く!) now 直後に +3M 3ヶ月間 +10y 10年間 Thursday, 25-Apr-1999 00:40:33 GMT 指定された時刻と日付 B<-cookie>パラメータはブラウザに、この後このスクリプトとの全ての トランザクション間、"魔法のクッキー"を提供することを伝えます。Netscape クッキーは有効期限のような面白い属性が入った特別なフォーマットを持っています。 セッション・クッキーを作成し、取り出すためにはcookie()メソッドを使ってください。 B<-nph>パラメータがtrue値に設定されれば、それはNPH(no-parse-header) スクリプトで機能するための正しいヘッダを出力させます。そのすべてのスクリプトが NPHであることを期待する、ある種のサーバで使うことは重要です。 B<-charset>パラメータはブラウザに送信される文字セットを制御するために 使うことが出来ます。与えられなければ、デフォルトはISO-8859-1です。 副作用として、これはcharset()メソッドも設定します。 B<-attachment>パラメータは添付にページを切り替えるために使うことが出来ます。 ブラウザによっては、ページを表示する代りにファイルに保存するためのプロンプトを 表示します。引数の値は保存されるファイルのための提案される名前です。 これが機能するためには、B<-type>を"application/octet-stream"にしなければ いけないかもしれません。 =head2 リダイレクション・ヘッダの作成 print $query->redirect('http://somewhere.else/in/movie/land'); ときには、ドキュメントをあなた自身が作成するのではなく、おそらくURLを 時刻やユーザの識別子をベースにより選択しながら、単にブラウザをどこかに リダイレクトしたいだけかもしれません。 redirect()関数はブラウザを他のURLにリダイレクトします。もしこのような リダイレクトを使えば、headerも出力してはB<いけません>。 私が提案できる1つのヒントは、あなたのサイトの別のドキュメントへの リダイレクトを作成したとき、相対リンクは正しく機能しないことです。これは、 いくつかのサーバが使うよく考えられた最適化によるものです。それを解決する 方法はリダイレクトするドキュメントの(http: 部分も含めた)完全なURLを 使うことです。 名前付き引数も使うことができます: print $query->redirect(-uri=>'http://somewhere.else/in/movie/land', -nph=>1); B<-nph>パラメータがtrue値に設定されれば、それはNPH(no-parse-header) スクリプトで機能するための正しいヘッダを出力させます。 Microsoft Internet Information Server (訳者注:原文では Internet Explorer)の ように、そのすべてのスクリプトがNPHであることを期待する、ある種のサーバで 使うことは重要です。 =head2 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ヘッダと開かれたタグを返します。 全てのパラメータはオプションです。名前付きパラメータ形式で、理解される パラメータは-title, -author, -base, -xbase そして -targetです (下記の説明をご覧ください)。Netscapeの非公式のBGCOLOR属性ような、 指定されたすべての追加のパラメータはタグに追加されます。 追加のパラメータは前にハイフンをつけなければいけません。 引数B<-xbase>は以下のように、タグを現在の位置から変えるために HREFを提供することを可能にします -xbase=>"http://home.mcom.com/" すべての相対リンクは、このタグからの相対と解釈されます。 引数B<-target>はすべてのリンクとページ上のフォームのための デフォルトのターゲット・フレームを指定することができます。 B<これはNetscapeブラウザでのみ機能する標準でないHTTP機能です!> これをどのように扱うかの詳細については、Netscapeのフレームに ついてのドキュメントをご覧ください。 -target=>"answer_window" すべての相対リングはこタグの相対だと解釈されます(訳者注:おそらく不要(?_?))。 B<-meta>引数でヘッダに任意のメタ情報を追加します。この引数はメタ情報の 名前/値の組が入った連想配列へのリファレンスを期待します。 これらは以下のような、ヘッダでの一連のタグに変わります: タグのHTTP-EQUIVタイプを作るためには、以下で説明するB<-head>を 使ってください。 B<-style>タグはあなたのコードにカスケーディング・スタイルシートを 入れるために使われます。さらに詳細な情報は「カスケーディング・スタイルシート」の セクションをご覧ください。 B<-lang>引数はタグにlanguage属性を入れるために使われます。 指定されなかったときのデフォルトはUS Englishのための"en-US"です。例: print $q->start_html(-lang=>'fr-CA'); B<-encoding>引数を、XHTMLのためのキャラクタ・セットを指定するために使うことが 出来ます。指定されなければデフォルトはiso-8859-1です。 B<-head>タグで他の任意のHTML要素をセクションに置くことができます。 例えば、あまり使われない要素をHEADセクションに置くためには、これを 使ってください: print start_html(-head=>Link({-rel=>'next', -href=>'http://www.capricorn.com/s2.html'})); 複数のHTML要素をセクションに入れるためには、単に 配列リファレンスを渡してください: 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 タグの作成方法です: print start_html(-head=>meta({-http_equiv => 'Content-Type', -content => 'text/html'})) JAVASCRIPTING: B<-script>, B<-noScript>, B<-onLoad>, B<-onMouseOver>, B<-onMouseOut>そしてB<-onUnload>パラメータがNetscape JavaScript呼出しを ページに追加するために使われます。B<-script>はJavaScript関数定義が 入ったテキストのブロックを示さなければなりません。このブロックは (HTTPではなく)HTML内部の