トップへ > Web Program Lab.> No.6 データの渡し方 その2
ウェブ・プログラムの研究所 Web Application Programming Lab.
一つ前にもどる 目次にもどる 次のページへ
●データの受け渡し方(データ入力の方法)その2

前回プログラムへのデータの渡し方(入力)について考えましたが、あれだけではいったい何をやっているのか???な状態だったと思います。そこで、今度はサンプルとしていくつか簡単なデータをやり取りするプログラムを作ってみたいと思います。


●選択に応じて内容を変える

まず、簡単な例からです。
利用者の選択に応じて、表示内容を変えるためのプログラムです。具体的には最初でやった「おみくじ」のようなプログラムになります。「おみくじ」の場合は画面を変化させるための振分けをサーバー内の時間によって行っていましたが、これを入力されたデータによって変化させる、という単純なものです。

プログラムの簡単な流れとしては下のようになります。

 入力(選択)画面(HTML)
  ↓
 プルダウンによる選択
  ↓
 クエリーを受けて処理
  ↓
 プログラム内で分岐
  ↓
 表示


前回は「おみくじ」だったので、今回は「血液型うらない」にしてみたいと思います。ウェブ上で血液型を聞いて、それに応じた内容を返す、というプログラムです。

■血液型占い(選択してチェックしてみて!)
A型 :
B型 :
O型 :
AB型:
とりあえずソースを見てみましょう。


01: #!/usr/local/bin/perl
02:
03: require 'jcode.pl';
04:
05: if ($ENV{'REQUEST_METHOD'} eq "POST") {
06:   read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
07: } else {
08:   $buffer = $ENV{'QUERY_STRING'};
09: }
10:
11: foreach (split(/&/, $buffer)) {
12:   ($keyword, $value) = split(/=/);
13:   $value =~ tr/+/ /;
14:   $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
15:
16:   # S-JISコード変換
17:   &jcode'convert(*value, "sjis", "", "z");
18:
19:   $value =~ s/\r//g;
20:   $value =~ s/\n//g;
21:
22:   $FORM{$keyword} = $value;
23: }
24:
25: if ($FORM{'bloodtype'} eq "A"){
26:   $hyoji = "きまじめ";
27: }elsif ($FORM{'bloodtype'} eq "B"){
28:   $hyoji = "ほがらか";
29: }elsif ($FORM{'bloodtype'} eq "O"){
30:   $hyoji = "おおざっぱ";
31: }elsif ($FORM{'bloodtype'} eq "AB"){
32:   $hyoji = "つかみどころがない";
33: }else{
34:   $hyoji = "?";
35: }
36: # ここからHTMLの表示です。
37: print <<"HTML";
38: Content-Type: text/html
39:
40: <html><head><title>test</title></head>
41: <body>
42: $FORM{'bloodtype'}型のあなたの性格<br>
43: $hyoji
44: </body></html>
45:
46: HTML
47:
48: __END__
*インデントにスペースを使っています。
 このままコピーしても動きません。
*左端の番号は便宜的に付けた行番号です。


解説をすると、、、

最初の行の「require 'jcode.pl';」

03: require 'jcode.pl';


これは入力された文字コードを変換するために「jcode.pl」というライブラリーを取り込む処理です。前回のデコードでも書きましたが、入力される文字コードによって文字化けとなる可能性があるため、これらを適切な文字コードに変換する必要があります。逆に入力される文字が英数だけならこの処理は要らないと思います。

次からの行が前回解説した部分になります。実は、今回のサンプル程度の入力ならこんなに複雑な処理をする必要もないのです。入力されるのは、「bloodtype」 という属性が「A,B,O,AB」 ということだけですので、「?bloodtype=**」という入力さえ処理できればいいはずです。しかも入力されるのは英文字だけです。(数字さえない!)

よって、10〜23行の処理をもっと単純に書き直すためには、


【入力処理を単純にした例】
05: if ($ENV{'REQUEST_METHOD'} eq "POST") {
06:   read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
07: } else {
08:   $buffer = $ENV{'QUERY_STRING'};
09: }
10: ($keyword, $value) = split(/=/);
11: $FORM{$keyword}= $value;

*太字の部分が10-23行を置き換えた部分


これだけでOKになってしまいます。(当然require 'jcode.pl'も不要)
では、なぜ前回のように複雑なことをしているのかということですが、外部からの入力データを汎用的に扱うことができるようにするためなのです。

入力というのは今回に限らず、プログラムをするときには必ず必要になってきます。その必ず必要になってくる部分を毎回その入力されるデータごとに合わせて処理をしているのでは、プログラムを作成するときの作業効率が悪くなるからです。

上の単純に書いた例では、一つのデータしか扱うことができません。このプログラムだけで終了ならいいのですが、もし、もう一つデータを受け取りたくなった場合には、それ用に書き換える必要もあります。また、英文字以外を使う場合には文字コードに応じた処理も、、、と考えると、前回のようにある程度一般化する必要があるのです。

こうすると、今回のサンプルで、血液型以外に生年月日と年齢を入力してもらおう、、、と言った場合でも、入力される部分を全く書き換える必要なくデータを取り込むことができます。

通常このように一般化(共通化)されて、何度も頻繁に利用される部分だけを抜き出してサブルーチン化します。(またはライブラリーやモジュール化する場合もあるでしょう・・・)よって、次のプログラムではこの入力を実行する部分だけをサブルーチンとして抜き出して処理しています。(事項を参照)

最後に、入力された内容にしたがって表示させるHTMLを作る部分ですが、前回までのprint命令とはちょっと違う書き方をしています。これはヒアドキュメントという手法です。


print <<"HTML";

ここに自由にテキスト、HTML等を書き込めます。

HTML

*HTMLの部分はどのような文字でもOK


これを使うと一行ごとにPrintを書かなくてもよくなりますし、ダブルクォーテーション(”)を(\)でエスケープすることも不要です。こんな便利なもの早く教えろ!と言われそうですが、、、

また、ヒアドキュメントで書き出された部分の改行は反映されますので、わざわざ「\n」を書かなくても良くなります。逆に、ここで改行して表記してしまうと出力結果にも改行は反映されるので注意が必要です。(<BR>の意味ではないです。念のため・・・)

それ以外は通常のPrint文と同じです。複数行OKなPrint文だと思えばOKでしょう。


●入力内容を保存してページとして表示する(アンケート)

上で解説したようなプログラムならJavaScriptで出来てしまいます。なので、それだけでは出来ないようなものをサンプルとして取り上げます。 今度は「カウンター」の応用編のようですが、アンケート集計です。
■アンケート調査です。
賛成:
反対:
今回も、とりあえずソースを見てみたいと思います。(ただ、ずいぶん長いソースになってきました・・・)

01: #!/usr/local/bin/perl
02:
03: require 'jcode.pl';
04:
05: &read_data;
06:
07: # count.datというファイルから現在のカウント数を読み込む
08: open (IN, "quest.dat");
09: @count=<IN>;
00: close(IN);
11:
12: # 改行コードを取り除く
13: chomp @count;
14:
15: # 現在のカウント数$countに1を追加
16: if ($FORM{'ans'} eq "yes"){ $count[0]++;}
17: elsif ( $FORM{'ans'} eq "no"){$count[1]++;}
18:
19: # print以外でもヒアドキュメントは使えるんです。便利!
20: $newdata = <<"DATA";
21: $count[0]
22: $count[1]
23: DATA
24:
25: # 1増加したカウントを保存
26: open (OUT, ">quest.dat");
27: print OUT $newdata;
28: close(OUT);
29:
30: # ここからHTMLでの表示
31: print <<"HTML";
32: Content-Type: text/html
33:
34: <html><head><title>test</title></head>
35: <body>
36: アンケート結果<br>
37: 賛成 : $count[0] 人<br>
38: 反対 : $count[1] 人<br>
39: </body></html>
40: HTML
41:
42: # サブルーチン化された読み込み処理
43: sub read_data(){
44:   if ($ENV{'REQUEST_METHOD'} eq "POST") {
45:     read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
46:   } else {
47:     $buffer = $ENV{'QUERY_STRING'};
48:   }
49:   foreach (split(/&/, $buffer)) {
50:     ($keyword, $value) = split(/=/);
51:     $value =~ tr/+/ /;
52:     $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
53:
54:     # S-JISコード変換
55:     &jcode'convert(*value, "sjis", "", "z");
56:
57:     $value =~ s/\r//g;
58:     $value =~ s/\n//g;
59:
60:     $FORM{$keyword} = $value;
61:   }
62: }
63: __END__


まず、最初の例との違いですが、入力されたデータを処理する部分をサブルーチン化しています。下の「&read_data;」というのは「read_data」という名前のサブルーチンの処理をしなさい、というPerlの命令です。


01: #!/usr/local/bin/perl
02:
03: require 'jcode.pl';
04:
05: &read_data;


43: sub read_data(){
44:   if ($ENV{'REQUEST_METHOD'} eq "POST") {
45:     read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
    ・・・
60:     $FORM{$keyword} = $value;
61:   }
62: }


5行目でそのように書くことで、今度は43行〜62行(茶色の部分)を実行するような命令になります。Perlでは「&***」でサブルーチンを呼び出し、「sub ***{}」でサブルーチンの処理を定義しています。

ですから、このようによく使う命令群をサブルーチン化することで、効率よくプログラムを書くことが出来ます。(これはPerlに限ったことではないですが・・・)

次に、アンケートデータを保存してあるファイルからデータを読み出します。このとき、「@count」という配列に読み込みます。テキストデータだと各行が配列の要素に一致します。「$count[0]⇒1行目、$count[1]⇒2行目、$count[2]⇒3行目」というようにです。


08: open (IN, "quest.dat");
09: @count=<IN>;
00: close(IN);
11:
12: # 改行コードを取り除く
13: chomp @count;


ですが、各要素の末尾には改行コードがついていて、処理するには不具合があるので13行目の「chomp」という命令で改行コードを取り除いています。

あとは、「yes」か「no」かで、集計処理を分けて最終的にそれを保存して終了、という処理になります。


15: # 現在のカウント数$countに1を追加
16: if ($FORM{'ans'} eq "yes"){ $count[0]++;}
17: elsif ( $FORM{'ans'} eq "no"){$count[1]++;}


書き込みをする条件を入力してもらうという点を除けば、基本的にはカウンターと同じ処理だと思います。簡単ですよね。これで入力データの処理について理解してもらえたでしょうか??


(2004/2/5 by あいまい)
一つ前にもどる 目次にもどる 次のページへ

トップへ > Web Program Lab.> No.6 データの渡し方 その2

copyright(C) 2001-2004 all rights reserved
『ウェブ・プログラムの実験場!』

by あいまいモード・コム(www.iMYmode.com)