[←Back]   5. 掲示板作りに挑戦しよう  [Next→]

   5-1 データを受け取ろう
掲示板を作るにはまず、掲示板に書き込まれた内容を受け取る必要がありますね。
そこで、最初に投稿者の名前とE-mailを受け取るプログラムを作ってみましょう。
下のform.cgiとform.htmlを同じフォルダに入れて、form.htmlを開いてください。

▼ form.cgi ▼
#!/usr/local/bin/perl

$comment=$ENV{'QUERY_STRING'};
print "Content-type: text/html\n\n";
print $comment;
exit;
$ENV{'QUERY_STRING'};は、4−6でも書いたようにCGIに送信された情報を指しています。

▼ form.html ▼
<HTML>
<BODY>
 <FORM ACTION="form.cgi">
 投稿者<INPUT TYPE="text" NAME="name"><BR>
 E-mail <INPUT TYPE="text" NAME="mail"><BR>
 <INPUT TYPE="submit" VALUE="送信">
 <INPUT TYPE="reset" VALUE="リセット">
 </FORM>
</BODY>
</HTML>
ここで、投稿者にxxx、E-mailにyyyと入力して送信すると、画面には
 name=xxx&mail=yyy
と表示されます。つまりCGIには、 「フォームのNAME=入力された値&フォームのNAME=入力された値&・・・」 の形でデータが渡されるわけです。 このため、入力された値だけを得るには、チョットした工夫が必要になります。

▼ form.cgi ▼
#!/usr/local/bin/perl

$data=$ENV{'QUERY_STRING'};
($name,$mail)=split(/&/,$data);
($name1,$name2)=split(/=/,$name);
($mail1,$mail2)=split(/=/,$mail);

print "Content-type: text/html\n\n";
print "名前:$name2 メール:$mail2";
exit;
まず最初に、CGIに渡された値を「&」で分割することで、フォーム1つ1つに分割します。
さらにそれを「=」で分割すれば、入力された値だけが取り出せるというわけです。


   5-2 文字化けはどうするの〜?
上のサンプルで、試しに投稿者のところに「」と入力して送信してみましょう。すると、%82%A0と表示されると思います。
当然、「読めないやんけ〜!」とツッコミが来るでしょう。

実は、CGIに渡されるデータは下のようなURLエンコーディングという規則にしたがって変換されています。
半角(1バイト)の英数字変換しない
* - . @ _変換しない
半角スペース+(半角のプラス)に変換
その他「%」+2桁の16進数の文字コードに変換
このため2バイトの文字や「=」等の記号は、読めるようにデコードしてあげる必要があります。
下がそのサンプルプログラムです。

#!/usr/local/bin/perl

require 'jcode.pl'; 
$data=$ENV{'QUERY_STRING'};

$data =~ tr/+/ /;
$data =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1) )/ge;
&jcode'convert( *value, 'sjis' );

($name,$mail)=split(/&/,$data);
($name1,$name2)=split(/=/,$name);
($mail1,$mail2)=split(/=/,$mail);

print "Content-type: text/html\n\n";
print "名前:$name2 メール:$mail2";
exit;
$data =~ tr/+/ /;では「+」を半角スペースに戻しています。
$data =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1) )/ge; で、その他の文字をデコードしてあげています。
この2行ついては、詳しい説明は省略します。デコードの時の決まり文句とでも思ってください(汗;)


   5-3 「POST」と「GET」ってなぁに?
上のサンプルで投稿者を「xxx」、メールアドレスを「yyy」を入力して実行すると、 ブラウザのURL表示欄に?name=aaa&email=bbbと表示されると思います。 このようにURLに送信するデータを埋め込んでCGIに渡す方法をGETメソッドといいます。

もう1つ、データを送るにはPOSTメソッドという方法もあります。
POSTの場合はデータはURLに埋め込まれずに、送信データ内に格納して送られます。
どちらの方式で送信するかは、<FORM>の中身を、下のように書き換えればOKです。

   GETメソッド……<FORM ACTION="form.cgi" METHOD="GET">
   POSTメソッド…<FORM ACTION="form.cgi" METHOD="POST">


ちなみに、METHODを省略したときにはGETメソッドになります。
上のサンプルがGETメソッドになったのは、このためですね。

次にデータの受け取り方ですが、GETメソッドの場合は5-2のプログラムでOKです。
しかし、POSTメソッドの場合はこれとは少し変わります。

▼ form.html ▼
<HTML>
<BODY>
 <FORM ACTION="form.cgi" METHOD="POST">
 投稿者<INPUT TYPE="text" NAME="name"><BR>
 E-mail <INPUT TYPE="text" NAME="mail"><BR>
 <INPUT TYPE="submit" VALUE="送信">
 <INPUT TYPE="reset" VALUE="リセット">
 </FORM>
</BODY>
</HTML>
まずこれが、POSTメソッドで送るように変更したform.htmlです。METHOD="POST"を追加しただけですね。
次に、cgiファイルは下のように変えます。

▼ form.cgi ▼
#!/usr/local/bin/perl

require 'jcode.pl'; 
read( STDIN, $data, $ENV{ 'CONTENT_LENGTH' } );

$data =~ tr/+/ /;
$data =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1) )/ge;
&jcode'convert( *value, 'sjis' );

($name,$mail)=split(/&/,$data);
($name1,$name2)=split(/=/,$name);
($mail1,$mail2)=split(/=/,$mail);

print "Content-type: text/html\n\n";
print "名前:$name2 メール:$mail2";
exit;
変えた部分はread( STDIN, $data, $ENV{ 'CONTENT_LENGTH' } );の行だけです。
環境変数「CONTENT_LENGTH」の長さ分、標準入力(STDIN)からデータを取得し変数「$data」に格納しています。


   5-4 受け取ったデータを保存しよう



[←Back]   BACK   [Next→]