トップへ > Web Program Lab.> No.2 動的ページ作成
ウェブ・プログラムの研究所 Web Application Programming Lab.
一つ前にもどる 目次にもどる 次のページへ
●画面を動的(ダイナミック)に作り出す

前回で、Webプログラムの仕組みの概要は理解できたのでは、、、と思います。そこで、ここでは簡単に毎回違う内容を表示するページを作ってみましょう。早速、サンプルを示したいと思います。


01: #!/usr/local/bin/perl
02:
03: # ここで、サーバーから日時の情報を取得します。
04: ($sec,$min,$hour,$day,$mon,$year,$week) = localtime(time);
05: $mon++;
06:
07: # 時間帯によってメッセージを分けるための処理です。
08: $message="Mid night!";
09: if ($hour >= 6){$message="Good morning!";}
10: if ($hour >= 12){$message="Good afternoon!";}
11: if ($hour >= 18){$message="Good evening!";}
12:
13: # ここからHTMLの表示です。
14: print "Content-Type: text/html\n\n";
15: print "<html><head><title>test</title></head>";
16: print "<body>";
17: print "今日は$mon月$day日です。<br>\n";
18: print "今は$hour時$min分です。<br>\n";
19: print "$message";
20: print "</body></html>";
21:
22: __END__

*左端の番号は便宜的に付けた行番号です。

プログラムの効率云々を言われるとつらいので、あまり突っ込まないで下さい。ですが、このプログラムを起動すると今日の日付と時刻、そして、時間帯によってメッセージが変わるページを作ることができます。

個別にプログラムの解説を簡単にしますと・・・

01:#!/usr/local/bin/perl

これは、前回も書きましたが、Perl本体が置かれているサーバーの場所です。

04: ($sec,$min,$hour,$day,$mon,$year,$week) = localtime(time);
05: $mon++;

timeはPerlの中でも特別な変数で、サーバーの時刻を返してくれます。ただ、timeの中身を表示させてみるとわかるのですが、このままでは人間が読める時間になっていません。正確にはUTC(国際協定時間)である1970年1月1日0時0分0秒からの累積秒数が返されるらしいのです。

これを自分で処理してもいいのですが、Perlで簡単に変換してくれる関数が「localtime()」です。これを更に、$sec=秒 $min=分 $hour=時 $day=日 $mon=月 $year=年 $week=曜日 ・・・というそれぞれの変数に格納します。ただ、なぜか月についてはカレンダーよりも1だけ少ない数字になるので、すぐあとに、 $mon++; と1足しています。( $mon++ とは $mon = $mon + 1; の省略系です。)

ここからが、実際に書き出されるHTMLとなります。
14行目の「Content-Type」は前回でましたが、ヘッダー情報として必要でしたよね?これに続いて、HTMLの文法どおり、普段書いているような形式で書き出します。

14: print "Content-Type: text/html\n\n";
15: print "<html><head><title>test</title></head>";
16: print "<body>";
17: print "今日は $mon$day 日です。<br>\n";
18: print "今は $hour$min 分です。<br>\n";

ただ、17行目を見ると、「print "今日は $mon 月 $day 日です。<br>\n";」となっており、print命令の中に、先ほどの時間を格納した変数が入っています。これが、表示されるときには、展開されて、今日の日付として書き出されます。たとえば、$mon = 10 , $day = 3 だとすると、画面上は「今日は10月3日です。」と表示されます。

ほとんどのプログラムでは、このようにして処理結果をHTML形式で表示させているんですね。

ここからが、動的(ダイナミック)に表示が変わる部分です。
08: $message="Mid night!";
09: if ($hour >= 6){$message="Good morning!";}
10: if ($hour >= 12){$message="Good afternoon!";}
11: if ($hour >= 18){$message="Good evening!";}
  ・・・
19: print "$message";
20: print "</body></html>";

最終的には「print "$message"」で表示をするのですが、その内容が、先ほどの時間 $hour によって変わります。結果として、
  • 0時〜6時には「Mid night!」
  • 6時〜12時には「Good morning!」
  • 12時〜18時には「Good afternoon!」
  • 18時〜24時には「Good evening!」
というように、時間に応じて表示を替えることができます。簡単ですね。

実際のサンプルを動かしているので、「こちら」をクリックしてみてください。(別窓)


●このソース(プログラム)を応用すると・・・

以上は、時間によってメッセージを替える、というプログラムだったのですが、もう少しゲーム性を持たせて見ましょう。
01: #!/usr/local/bin/perl
02:
03: # ここで、サーバーから日時の情報を取得します。
04: ($sec,$min,$hour,$day,$mon,$year,$week) = localtime(time);
05:
06: # 時間帯によってメッセージを分けるための処理です。
07: @message=("大吉","中吉","小吉","小吉","吉","吉","吉","末吉","凶","大凶");
08: $sec = chop $sec;
09:
10: # ここからHTMLの表示です。
11: print "Content-Type: text/html\n\n";
12: print "<html><head><title>test</title></head>";
13: print "<body>";
14: print "本日 $mon 月 $day 日の運勢!<br>\n";
15: print "$message[$sec]";
16: print "</body></html>";
17:
18: __END__

*左端の番号は便宜的に付けた行番号です。

このプログラムが起動されると、画面には今日の運勢が表示されます。おみくじですね。
ちょっとインチキといえばそうなのですが、、、おみくじの出る運勢を、引いた時間(ここでは、秒の一桁目)で決めています。 ちゃんとするにはランダムを使うとかできるのですが、、、ランダムの説明も面倒だったので、こんな方法もある?くらいに思ってください。

先ほどのプログラムと変わった所を解説すると、、、 先ほどは、時間の変数 $hour の大きさを「if」文で分岐する方法でしたが、今回は秒の変数 $sec の一桁目を使って、アクセスした時間で、内容を変えているだけです。

07: @message=("大吉","中吉","小吉","小吉","吉","吉","吉","末吉","凶","大凶");
08: $sec = chop $sec;

@messageはPerlでは配列変数をあらわします。この配列 $message[0] 〜 $message[9] にそれぞれの内容を割り当てています。

次の「 $sec = chop $sec; 」ですが、chop とは、文字列から一番最後の文字だけを切り取る関数です。 chop $sec; で秒の数字から一桁目を取り出して、再び自分自身 $sec に代入しています。

この $sec を、メッセージを表示するときの配列の添え字として $message[$sec] というようにすることで、1のときは $message[1] の内容である「中吉」が、4のときは $message[4] の内容である「吉」が表示される仕組みです。単純でしょ?このサンプルは便宜上、時間を使ったかなりインチキな占いなので、本格的にしたい方は、ランダムや他のアルゴリズムを使ってがんばってみてください。

インチキおみくじのサンプルは「こちら」です。(別窓)


●ブラウザ側とサーバー側でのプログラムの違い

ですが、この程度なら JavaScript等でもできちゃいますよね、、、。 JavaScript などで出来てしまうことは、できるだけ JavaScript等でした方がサーバーへの負荷も少なくなっていいのです。むしろ、最初の時間でメッセージを替えるプログラムの場合、はJavaScriptで書く方が適当かも知れません。ということで、JavaScript版を下に書いてみました。

(最初のプログラムのJavaScript版 - 他のHTML部は省略)

01: <script language="JavaScript" type="text/javascript">
02:
03: // 時刻の取得
04: cTime = new Date();
05:
06: month = cTime.getMonth();
07: date = cTime.getDate();
08: hour = cTime.getHours();
09: minute = cTime.getMinutes();
10:
11: // メッセージの分岐
12: message="Mid night!";
13: if (hour >=6){message="Good morning!";}
14: if (hour >=12){message="Good afternoon!";}
15: if (hour >=18){message="Good evening!";}
16:
17: // HTMLの表示
18: document.write("今日は "+month+"月"+date+"日です。<br>");
19: document.write("今は "+hour+"時"+minute+"分です。<br>");
20: document.write(message);
21:
22: </script>


この手のスクリプトはあちこちのサイトで使われていますよね?PerlなどのWebプログラムで書いても、JavaScriptで書いても基本的な動作はかわりません。が、強いて違いを挙げるとすれば、「時間」です。

Perlで書いたWebプログラムの場合、サーバーで「time変数」を利用してサーバーの時刻を基準にメッセージを出していましたが、JavaScriptは各個人が見ているパソコンの時間から「new Date();」が呼び出されるので、パソコンの時間が基準になります。ですから、もしも自分のパソコンの時間がずれていたりすると、メッセージの表示が個人でバラバラになる可能性があります。

また、当然、JavaScriptは各パソコンで動くので、ブラウザで「ソースの表示」を選ぶと、プログラムの中身が見えますが、Webプログラムは都度HTMLを生成していますので、HTMLしか見えません。

セキュリティー設定 最後に、欠点があるとすればブラウザ側で処理される JavaScript のようなプログラムは、見ている人がオフにしてしまうと、期待しているように動かないということです。 例えば、インターネットエクスプローラ(以下IE)の「ツール」>「インターネットオプション」の「セキュリティ」タブにあるセキュリティレベルを初期値の「中」から「高」にされてしまうと、JavaScriptのような機能が動かなくなってしまいます。

また、この例のように単純なものならいいのですが、複雑な処理を JavaScript系で書くと、ブラウザのバージョンに依存することが多く、IE6.0では動くけど、IE5.0ではダメだった・・・なんてことが多々あります。皆さんも、ページをあちこち見ていて「スクリプトエラー」に遭遇したことはないですか?

このように、見ている人のパソコンの環境に依存しないページが作れるとういのが Webプログラムの利点ということになりそうです。ただ、処理の結果を JavaScript で書き出す・・・という場合には注意が必要ですが。

ということで、時間によってメッセージが替わるプログラムを2つ比較してみてください。JavaScript版はソースの表示をするとプログラムが見えますが、PerlのWebプログラム版はHTMLだけしか見えません。(当然JavaScript版はJavaScriptがオンになっていないと見えませんが・・・)

また、JavaScript版の時刻とCGI版の時刻の違いに注目してみてください。JavaScript版は、いま使っているあなたのパソコンの時間が表示されていますが、CGI版はサーバー側の時間です。
  • JavaScript「こちら」をクリックで(別窓)
  • Perl & CGI「こちら」をクリックで(別窓)

次回は、いよいよ、サーバーへのファイルの保存を理解するために、カウンターを作ってみたいと思います。


(2003/6/9 by あいまい)
一つ前にもどる 目次にもどる 次のページへ

トップへ > Web Program Lab.> No.2 動的ページ作成

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

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