ここでは、フォームからデータを受け取るでフォームから送られてくるデータの形式を理解したうえで、データを読み込みそれを適切に表示するCGIプログラムを作成する。
まずは、フォームの例にあるフォームをform-ex.htmlというファイル名で保存せよ。このフォームから、以下のdispdata.cgi というCGIプログラムを実行する。dispdata.cgiは、送られてきたデータを読み込んで、その内容をそのまま表示する。
#!/usr/bin/env perl print "Content-Type: text/html\n\n"; &decode; print "<html><body><h1>Display direct data which is received CGI data</h1><pre>\n"; $sports = $tags{'sports'}; print "sports = ", $sports, "\n"; $baseball = $tags{'baseball'}; $soccer = $tags{'soccer'}; $basket = $tags{'basket'}; $tennis = $tags{'tennis'}; $golf = $tags{'golf'}; print "baseball = ", $baseball, "\n"; print "soccer = ", $soccer, "\n"; print "basket = ", $basket, "\n"; print "tennis = ", $tennis, "\n"; print "golf = ", $golf, "\n"; $dept = $tags{'dept'}; print "dept = ", $dept, "\n"; $s_id = $tags{'student_id'}; print "student_id = ", $s_id, "\n"; $name = $tags{'name'}; print "name = ", $name, "\n"; $com = $tags{'comment'}; print "comment = ", $com, "\n"; print "</pre></body></html>\n"; #------------------------------------------------------------ # cgi.pl - decode CGI input. # by ETO Kouichirou <t91069ke@sfc.keio.ac.jp> # date 1994/05/11 # # Usage: # # &decode; # ... # $name = $tags{'name'}; sub decode { local($args, $n_read, *terms, $tag, $value); if ($ENV{'REQUEST_METHOD'} eq "POST"){ $n_read = sysread(STDIN, $args, $ENV{'CONTENT_LENGTH'}); } else { $args = $ENV{'QUERY_STRING'}; } @terms = split('&', $args); foreach (@terms) { ($tag, $value) = split(/=/, $_, 2); $otags{$tag} = $value; # original tags $tags{$tag} = &unpack($value); # tags is global } } sub unpack { local($value) = @_; $value =~ s/\+/ /g; $value =~ s/%(..)/pack("c", hex($1))/ge; return $value; } sub unspecial { local($value) = @_; $value =~ s/&/&apm;amp;/g; $value =~ s/</</g; $value =~ s/>/>/g; return $value; }
PerlでCGIプログラムを書く場合に便利な仕組みがライブラリやパッケージという形で色々と提供されている。ここでは、江渡 浩一朗 氏が1994年に作成したCGIパッケージを一部改変して使っている。プログラムの後半の部分がそうである。
この場合、&decode としてdecode手続きを呼び出せば、 $tags{'コントロール名'}とすると、コントロール名で指定したデータ(コントロール値)が得られる。 例えば、上の例では、フォームのラジオボタンでサッカーを選んだ場合、コントロール名は、 "sports"でコントロール値は"2"のはずであるから、cgi{'sports'}と書くと "2" という値が得られる。上の例では、$sports = $tags{'sports'}として、いったん変数$sportsに代入してから使用している。
単にデータを表示するだけではおもしろくないので、表示の内容を工夫してみる。
#!/usr/bin/env perl print "Content-Type: text/html\n\n"; &decode; print "<html><body>\n"; $sports = $tags{'sports'}; $s_id = $tags{'student_id'}; $name = $tags{'name'}; if ($s_id eq "") { $s_id = "未記入"; } if ($name eq "") { $name = "名無し"; } print "学籍番号", $s_id, "の", $name, "さんは、"; if ($sports) { @sports_a = ("野球", "サッカー", "バスケットボール", "テニス", "ゴルフ"); print $sports_a[$sports-1]; print "が一番お好きなのですね。\n"; } else { print "一番お好きなスポーツを答えていただいておりません(;_;)\n"; } print "</body></html>\n"; #------------------------------------------------------------ # cgi.pl - decode CGI input. # by ETO Kouichirou <t91069ke@sfc.keio.ac.jp> # date 1994/05/11 # # Usage: # # &decode; # ... # $name = $tags{'name'}; sub decode { local($args, $n_read, *terms, $tag, $value); if ($ENV{'REQUEST_METHOD'} eq "POST"){ $n_read = sysread(STDIN, $args, $ENV{'CONTENT_LENGTH'}); } else { $args = $ENV{'QUERY_STRING'}; } @terms = split('&', $args); foreach (@terms) { ($tag, $value) = split(/=/, $_, 2); $otags{$tag} = $value; # original tags $tags{$tag} = &unpack($value); # tags is global } } sub unpack { local($value) = @_; $value =~ s/\+/ /g; $value =~ s/%(..)/pack("c", hex($1))/ge; return $value; } sub unspecial { local($value) = @_; $value =~ s/&/&/g; $value =~ s/</</g; $value =~ s/>/>/g; return $value; }
学籍番号や名前が未記入の場合には、例えば、if ($s_id eq "") { $s_id = "未記入"; } として、未記入という文字列を代入していることに注目せよ。また、一番好きなスポーツに何も選択していない場合は、 $sportsは、"" の値を持つ。その場合、if ($sports) { はsportsが""であるから成り立たなく、else { 〜 } の部分が実行されるのである。
sportsが選択されている場合は、配列@sports_aを使って対応するスポーツ名を表示している。 配列の添え字は0から始まるが、この場合、野球が1、サッカーが2、 バスケットボールが3という風に1から始まっているので、$sports-1 として1を引いていることに注目せよ。