Perl/CGI研究室 'PERL-LABO'

Perl/CGI研究室 'PERL-LABO' TOPへ
戻る(History.Back)

フォームデータを画面に一覧表示

研究内容

フォームデータの内容を全部、画面に一覧表示する研究です。

詳細

作りたいもの

フォームからのデータを受信する方法は分かりました。 これで、メールフォームとか、アンケートフォームとか、 いろんなCGIプログラムを作っていくことができます。 で、そのために、「フォームデータの内容を一覧表示する」というCGIプログラムを作りましょう。

なんのために?という感じもありますが、これからフォームからデータを受信するCGIプログラムを作るときに、 まずフォームを作って、そのフォームから CGIプログラムに意図した通りにデータが送られていることを「フォームデータの内容を一覧表示する」CGI プログラムで確認して、 それからCGIプログラム作成にとりかかる、という感じで使えると思います。

…というより、そういうCGIプログラムが実際に欲しいなと思ったので作るのであります (^^

結果

連想配列に入っている全てのデータを処理するには

フォームから送られてくるデータは、作成した getformdata 関数によって連想配列に入れられます。 ですから、ここで作成するCGIプログラムというのは、 連想配列の内容を画面に表示するCGIプログラムということになります。

連想配列の全てのキーと値を画面に表示するにはどうしたらいいでしょうか。 これ、環境変数の研究のところで少し研究しました。 連想配列のキーを配列にしてくれる keys 関数と、 配列の全ての要素について処理を行う foreach 文を使って、次のようにするんでした。

foreach (keys(%連想配列)) {
	$_ にキーが入っているので処理を行う
}

これを使っても、やりたいことはできますが、連想配列の全ての要素にアクセスしたい場合、 each 関数と while 文を組み合わせて次のようにするのがいいようです。

while (($key, $val) = each(%連想配列)){
	$key にキー、$val に値が入っているのでなんか処理する
}

each 関数というのは、連想配列から1個ずつキーと値のペアを取り出す関数なんだそうです。 全部のペアを取り出すと未定義値というものを返して、それで while 文が終了するので、 上のは結局、連想配列の全ての要素にアクセスするという機能になります。

keys 関数とforeach 文を使ったやり方の方がなんだか分かりやすく、使いやすいような気がするのですが、 keys 関数を使ったやり方よりも each 関数を使ったやり方の方が、実行速度が速いとか、CPU負荷が少ないといった メリットがあるんだそうです。というのは、foreach の方は keys 関数でキーを配列にするっていう 処理を行います。例えば連想配列が100万個のキーと値のペアを持っているとき、 keys 関数は100万個のキーを配列にするっていう処理をするわけですから、 これは結構大変ですね。each 関数を使ったやり方の場合、これがないので keys 関数を使ったやり方より 場合によってはずっと速くてCPU負荷も少なくなります。 CGIプログラムはできるだけCPU負荷が小さくなるように作りたいですから、 連想配列の全ての要素にアクセスしたいときは each 関数を使いましょう! ただし、キーをソートしてから処理したい場合なんかはやっぱり keys 関数を使う必要がありますけども。

作成したCGIプログラム

printformdata1.cgi
#!/usr/bin/perl

require 'getformdata.pl';

%formdata = plab::getformdata();

print "Content-type: text/html\n";
print "\n";

while (($key, $val) = each(%formdata)) {
	print "$key = $val<br>";
}

実行結果

試しに簡単なフォームを作ってみました。 送信ボタンをクリックしてみてください。

(inputタグのname)(inputタグ)
input1
input2
input3

考察

ん?表示される順番が…

動きました。でも…アレ?表示される順番がでたらめです。 input1、input2、input3 の順番で表示して欲しいですけど、 そうはならずに、しかも送信するたびに表示される順番が違います。 これはつまり、連想配列には順番みたいなものは一切なくて、 順番に関してはでたらめになるっていうことですね…。 これでもいいんですが、なんだか気持ち悪いです。

…ということで、せっかく each 関数の使い方を覚えたところですが、 表示される順番を一定にするために、環境変数の表示のところで学んだ keys 関数、sort 関数と foreach 文を使った次のやり方を使うように変更しましょう。

foreach (sort(keys(%連想配列))) {
	$_ にキーが入っているので処理を行う
}

each 関数を使った方が処理速度などの面でメリットがあるとはいえ、 フォームの動作確認用のCGIプログラムですし、データの数はそれほど多くないですから こちらでもOKですね。

作成したCGIプログラム

printformdata.cgi
#!/usr/bin/perl

require 'getformdata.pl';

%formdata = plab::getformdata();

print "Content-type: text/html\n";
print "\n";

foreach (sort(keys(%formdata))) {
	print "$_ = $formdata{$_}<br>";
}

実行結果

今度は、動作確認のためにわざと順番をでたらめにしてみました。 送信をクリックしてみてください。

(inputタグのname)(inputタグ)
input3
input1
input2

考察

動きました

ちゃんと、キーでソートされてフォームから送られたデータが全部画面に表示されました。 本当は、フォームの順番通り、上から順に表示してくれる方が嬉しいですけど、 getformdata 関数が連想配列を返すので、それをやるには getformdata 関数になにかを修正しなきゃいけません。 そこまでやる必要はないだろう、ということでこれで完成です。

結構便利だと思いますよコレ

簡単なプログラムですが、結構便利に使えると思います。 こういうものを先に作っておくと、後で楽ができるかなと思います。

分かったこと

  1. 連想配列の全ての要素にアクセスするには、while($key, $val) = each(%連想配列)) { 〜 } のようにします。
    こうすると、foreach (keys(%連想配列)) { 〜 } とするより速度が速くてCPU負荷が少ないです。
  2. 連想配列には順番がありません。each 関数を使うと順番がバラバラなので、
    キーの並び方を揃えたい場合は foreach (sort(keys(%連想配列))) { 〜 } を使うといいです。
Perl/CGI研究室 'PERL-LABO' TOPへ
戻る(History.Back)

Copyright (c) 'PERL-LABO' All Rights Reserved.  リンクフリーです。