【LEVEL2】 FORMからの情報を取得する。
続いては、HTMLのFORMより送られた情報をCGIで取得する方法を学びましょう。FORMってなにかって?
「ここ(POST)」又は「ここ(GET)」にあるような入力用のHTMLです。
こ のような入力欄に入力してもらった情報がサーバに送られて、そして受け取ったCGIがデータを処理するわけですね。実は、このFORMからデータを送る方 法が二種類あるんです。ひとつは「POST」形式、もう一つが「GET」形式。それぞれ利点欠点があるのですが、どちらを使用しているかによって受け取る 際の方法も変わってきます。利点欠点に関しては課題で出すので自分で調べてみましょう。さてさて、うん。面倒ですね。でも見た目はどちらも変わらないので さらにややこしい。
二つの中身を見ると見えない部分が少し違います。
---------------- POST形式 -----------------
<html>
<head><title>FORM TEST</title><head>
<body bgcolor="#ffffff">
<form method="POST" action="test04.cgi">
<center><font size=+2>FROM TEST</font></center><br>
◎お名前:<input type=text name="handle" size="30" maxlength="30"><p>
◎E-MAIL:<input type=text name="email" size="30" maxlength="30"><p>
◎HOME PAGE:<input type=text name="homepage" size="30" maxlength="90"><p>
<center>
<input type=submit value="決定する"><input type=reset value="リセット">
</center><br>
</form>
</body>
</html>
----------------- GET形式 -------------------
<html>
<head><title>FORM TEST</title><head>
<body bgcolor="#ffffff">
<form method="GET" action="test04.cgi">
<center><font size=+2>FROM TEST</font></center><br>
◎お名前:<input type=text name="handle" size="30" maxlength="30"><p>
◎E-MAIL:<input type=text name="email" size="30" maxlength="30"><p>
◎HOME PAGE:<input type=text name="homepage" size="30" maxlength="90"><p>
<center>
<input type=submit value="決定する"><input type=reset value="リセット">
</center><br>
</form>
</body>
</html>
さ て、先述がPOST形式、後述がGET形式です。間違い探し。どこが違うのでしょう。という冗談はさておき、<form method="POST / GET">なる部分が違うのです。ここが違うだけで全く異なる方法でデータを送ります。上記二つは、後ほど使いますので、それぞれ、form01.htm と form02.htm というファイル名で保存して、サーバへアップロードしておきましょ。しつこいけど、保存はTEXT形式ですからね。
POSTにしてもGETにしても情報をサーバへ送るわけですが、サーバが一時格納する場所も異なります。ですから当然CGIから格納された情報を引き出す方法も変わるわけですね。
詳 しく説明するとGETで送信された情報は、「環境変数のQUERY_STRING」という中に、POSTで送信された情報は「標準入出力のSTDIN」に 格納されてます。先に出てきた環境変数には他にも特殊な情報が格納されてたりしたりされたりします(謎)。ついでなので主なものを記載しましょう。
- QUERY_STRING ->GETから送信されたデータの格納庫
- CONTENT_LENGTH ->POSTで送信されたデータ長の格納庫
- REQUEST_METHOD ->データタイプ(POST or GET)の格納庫
- REMOTE_HOST ->接続者のHOST情報の格納庫
- REMOTE_ADDR ->接続者のIP名の格納庫
- HTTP_USER_AGENT ->接続者の使用PCと使用ブラウザの格納庫
- HTTP_COOKIE ->クッキー情報の格納庫
てな具合です。何を偉そうに!と思ったあなたは正解です。私も先程調べました。他にも山ほどあるしね。ようするに覚えなくたって必要な時に必要なものを調べたらいいわけだし、良く使うものは勝手に覚えます。ということです。
環境変数からデータを引き出すには、$ENV{'ほにゃらら'}なるものを使用します。つまり、GETで送られたデータは・・・。
$string = $ENV{'QUERT_STRING'};
としてあげれば、$stringの中に取り出せるわけですね。ここでPERLのルール。データを格納する数値を変数といいます。変数名は好きなように決めて良いのですが、頭は必ず「$」ではじめます。「¥」だの「$」だのやたらお金にまつわる言語ですね。つまり・・・。
$buffer = $ENV{'QUERY_STRING'};
だっ てよいわけです。細かい事を言うと使えない言葉もあります。使えなかった時は運がなかったと言うことで諦めて他の言葉にしてください。むろん半角英数ね。 これは常識。これでGETの場合はよいわけですが、POSTは格納先が違うので取り出し方も変わります。POSTデータは・・・。
read ( STDIN, $string, $ENV{'CONTENT_LENGTH'});
と 命令して取り出します。STDINと$bufferが何者かはすでに分かりますよね。一応説明しますか?STDINはPOSTデータの格納 庫、$stringは取り出し先の変数です。むろん先と同じで、$bufferとか別名でもOKです。$ENV{'CONTENT_LENGTH'}は格 納されてるデータの長さですね。実は、readという命令はちょっと高級で$stringに格納する長さを指定してあげないと駄目なんです。
さぁ さぁこれでPOSTデータもGETデータも取得する方法が分かりましたよ!でもこれあまり良いできとは言えないのですよね。なぜって、これだと、GETか POSTの何れかしかデータを引きだせない。実はCGIを自分で作成すると分かるのですが、どちらも使いたくなるのです。ということで人類の英知を注いで どちらでもOKにしてしまいましょう。
if ( $ENV{'REQUEST_METHOD'} eq "POST" ) {
read (STDIN, $buffer, $ENV{'CONTENT_LENGTH'};
} else {
$buffer = $ENV{'QUERY_STRING'};
}
いかにもプログラムらしくなりました。これでどっちでもOKです。
大切な構文を使用したのでしっかり説明しましょう。まず、IF文を使いました。
if (条件1) {その1} else {その2}
と 使用するのですが、大体言葉を見ると分かるかな。もし条件1ならそ「その1」を、そうぢゃなければ「その2」を実行しなさいという意味です。このIF文は 良く使うのでここで覚えてしまいましょ。上記は、もしPOSTならREADから、そうぢゃなければ$ENV{'QUERY_STRING'};からデータを$bufferに格納しなさいと命令したのです。
条 件文にしようしている「eq」は両辺を比較して同じかどうか?と言う意味です。「==」とイコールを二つ続けても同じ意味になります。な ぜ、$ENV{'REQUEST_METHOD'} = "POST" としないのか。実は「=(一個だけ)」は、PERLでは代入の意味なので、$ENV{'REQUEST_METHOD'} = "POST" としてしまうと、$ENV{'REQUEST_METHOD'} にPOSTという文字を入れろ。という意味になってしまうのです。今は、$ENV{'REQUEST_METHOD'} がPOSTなのかどうか比較したいわけですから、代入を意味する「=(一個だけ)」は使えないのです。比較を意味する「eqまたは==(二個続けて)」を 用います。
比較として使用するものをまとめると・・・。
- == (eq) 等しい
- != (ne) 等しくない
- < (lt) より小さい
- > (gt) より大きい
- >= (le) より大きいか等しい
- <= (ge) より小さいか等しい
- <=> (cmp) 比較
となります。数式を使用しても()内の文字列でも、どちらを使用しても同じ意味です。さて実例に移りましょう。
-------------------- 実際例 ----------------------
#!/usr/local/bin/perl
if ( $ENV{'REQUEST_METHOD'} eq "POST" ) { read ( STDIN, $buffer, $ENV{'CONTENT_LENGTH'} ); }
else { $buffer = $ENV{'QUERY_STRING'};}
print "Content-type: text/html\n\n";
print "<html>\n";
print "<head><title>CGI PRINT TEST</title></head>\n";
print "<body bgcolor=\"#ffffff\">\n";
print "BUFFER=[$buffer]<br>\n";
print "<center><a href=\"mailto:webmaster\@supertak.com\">E-MAIL</a></center><br>\n";
print "</body></html>\n";
exit;
「ここ(POST)とここ(GET)」にテストを設置していますのでクリックしてみましょう。
なにか適当なものを入力して実行してください。入力したものが表示されると思いますが、なにやらちょっと変ですよね。例えば日本語を入れると化け化けでしょ。それに入力カラムのデータが全部くっついてる。これらの解決は少々複雑なので次のLEVELで紹介します。