真里:加藤真里 シレ:シレスト=ノイデルファーム
シレ:前回はCGIのファイル名のあとに"?"と、それに続いて何やら暗号じみたデータを指定することでCGIプログラムへとデータを渡し、perlでそれを復元する方法についていろいろやりましたが……
真里:えっと、あれぢゃ掲示板作れないんだけど。
シレ:正確に言うと「かなりの長文が書き込まれる掲示板」は作れないということです。
真里:……って、え?だってさ、あれって直接URL入れるところに打ち込まないといけないんでしょ?
シレ:検索エンジンでいちいちあんなところに暗号みたいな文字を打ち込んでますか?
真里:……あ。そーいえばふつーに、四角いマスに文字入れて、「検索」ボタンで……
シレ:はい。前回やったことと同じことが、<FORM METHOD=GET
... >というHTMLタグで実現できます。「1行掲示板」やWebチャット程度ならあれでも十分です(FORMの書式の勉強は他のWebページやHTMLタグの解説本を見るとよいでしょう。)。
ただし、GETで送れるデータの大きさには、制限がある場合が多いんです。
真里:掲示板へのカキコがなんか知らないけど途中でちょん切れた!ってことがあるかもしれないわけね。うーん。……じゃぁさ、もしかしてCGIってそんなヘッポコだったの!?
シレ:いいえ。そのための、つまり比較的大きいデータを送るために<FORM METHOD=POST ... >というタグを使う「POST方式」があります。
真里:なんだぁ、GETをPOSTに入れ替えるだけだし。さぁて、これで掲示板は……
(しばらくして)
真里;って……できないぢゃないぃぃぃ!なんでよぉぉぉ、真里ちゃんの日頃の行いってそんなに悪かった!?それとも……も、もしや、これはインカ帝国の呪い!?
シレ:……あ、あの……POSTに変えただけではできませんよ……
真里:だったら早く言ってよぉぉ……
シレ:慌てないでくださいよ、真里さんも……さて、POSTのデータを拾うためには、前回のように$ENV{'QUERY_STRING'}を読み込むだけでは足りません。というわけで、早速ソースのほうを。
read ( STDIN, $data, $ENV{'CONTENT_LENGTH'}
);
$data =~ tr/+/ /;
$data =~ s/%([\da-f]{2})/pack("C", hex($1))/eig;
真里:……って……1行変わっただけのよーな気も……このreadとかなんとかいうモノになっただけ。
シレ:まさにそのとおりです。この read ( STDIN, $data, $ENV{'CONTENT_LENGTH'} ); という部分は、熟語みたいなものですから丸暗記してください。ただし2つ目の$dataの所には、自分の好きな変数が入れられます。
真里:STDINっていうのと、$ENV{'CONTENT_LENGTH'} って何?
シレ:正式にはSTDINというのは「標準入力」といいますが、CGIを作るだけなら「フォームで送ってきたデータ」と思っていただいて支障ありません。また、$ENV{'CONTENT_LENGTH'}
は送られてきたデータの大きさです。つまり、先程の1行を日本語に訳すと……
「フォームで送って来たデータをそっくりそのまま読み込んで$dataという入れ物の中に入れてね」
ということなんですよね。
真里:ふぅん……ま、とにかくこーいうふうに書いておけば使えるのよね。
シレ:フォームついでに……今の状態だと「名前」「URL」とかを入力するマスを作っても、全部くっついた状態で流れてきてしまいますよね?それを分割するためのソースも書いておきます。暇があれば意味を考えてみて下さい。
read ( STDIN,
$buffer, $ENV{'CONTENT_LENGTH'} ); @pairs=split(/&/,$buffer); foreach $pair ( @pairs ) { ($key,$value) = split( /=/, $pair ); $value =~ tr/+/ /; $value = s/%([\da-f]{2})/chr(hex($1))/eig; $FORM{$key} = $value; } |
シレ:これで$FORM{'name'}というふうにすると送られて来たフォームの中のnameという名前の部分が取りだせます。
[次回に続く……]
←PREV | NEXT→