ここでは、フォームからデータを受け取るでフォームから送られてくるデータの形式を理解したうえで、データを読み込みそれを適切に表示する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を引いていることに注目せよ。