ウェブ・プログラムの研究所 Web Application Programming Lab.

一つ前にもどる 目次にもどる 次のページへ

掲示板のページ処理の仕方

掲示板の表示はデータファイルからデータを読み出してHTML形式にするだけですが、記事の件数が多くなってくると(しかも、保存できる記事数がおおいと)全てのデータをHTML形式にして表示するのに時間がかかります。

そこで、たいていの掲示板では記事を「最初の1件〜20件まで表示」「次の20件を表示」というように、ページ処理がされています。このページ処理はどのように行えばいいのでしょうか?

まず、最初にする必要があるのは、「書き込まれたデータのどこからどこまでを表示させるか」ということをプログラムに教えることです。プログラムへはQueryStringsや標準入力から必要なデータを入力する必要があります。

例えば、、、

program.cgi?page=20

もしくは

<input type="hidden" name="page" value="20">

というようにです。

これを以前にデータの取り込みで行ったようにハッシュ化して、プログラムで扱えるデータとします。このデータを利用して必要なデータを取り出します。

MySQLのようなデータベース連携をしてデータを作成しているわけではないので、SQLでデータの取り出しをするわけではありません。実際には下のように「open();」関数を使ってファイルを全て開くことになります。(これは前回とかわってません。)

(ソースの一部:行番号は便宜上つけてます。)

01: # 記事の出力
02: # logfile.datから記事データを読み込む
03: open (IN, "logfile.dat") || &error("error");
04: @logdata=<IN>;
05: close(IN);
06:

開いたデータは

「@data=<IN>」

のように配列に取り込まれることになるので、 この配列の欲しいデータだけを抜き出して表示するようなプログラムに変更すればいいはずです。

そこで、表示させるループ処理(for{})の部分を書き換えます。 一度に表示させたい件数だけループさせて、 指定の配列に入ったデータを表示する、という処理をすればいいわけです。単純ですね。

実際にプログラムに適用してみる

では、実際にこのループ処理も含めた一連のページ処理を見てみたいと思います。

下のソースは、前回の掲示板表示プログラムの一部を改造したものです。 行番号をあわせれば見やすかったのですが、、、すみません。 そこまではしてありませんm(__)m

前回の表示処理はデータファイルから記事を読み取って、全て表示するというものでした。 ですから、「foreach」という処理で全ての配列を処理していました。今回は、 決まった数だけ表示させるので、「for」を使っています。 順番に解説していきたいと思います。

(ページ処理をされたソースの一部:行番号は便宜上つけてます。)

01: # 記事の出力
02: # logfile.datというファイルからデータを読み込む
03: open (IN, "logfile.dat") || &error("error");
04: @logdata=<IN>;
05: close(IN);
06:
07: $total_num = @logdata; # 記事の数
08: $start_page = $FORM{page}; # 表示する記事の位置
09: $back_page = $FORM{page}-5; # 戻りのページ
10: if ($back_page < 0){
11:  $back_page = 0;
12: }
13: $end_page = $FORM{page}+5;
14: if ($end_page > $total_num){
15:  $end_page = $total_num;
16: }
17:
18: print <<"HTML";
19: <a href="sbbs_read.cgi?page=$back_page">戻る</a> -
20: <a href="sbbs_read.cgi?page=$end_page">進む</a>
21: ($start_page / $total_num)
22: HTML
23:
24: for ($i=$start_page;$i < $end_page;$i++){
25:  # 各行のデータをカンマで区切ってそれぞれの変数へ
26:  ($no,$u_name,$subject,$comment,$date) = split(/\,/,$logdata[$i]);
27:  # ヒアドキュメントによる各記事の生成
28:  print <<"HTML";
29:
30:  ここにHTMLで掲示板の記事を書き出します。
31:
32:  HTML
33: }

前回と違うのはデータを読み出した直後です。今回は読み出すときに「$FORM{page}」という変数を受け取って、その記事番号から決まった数だけの記事を表示するようにしているので、その処理を7行目から9行目でしています。

07: $total_num = @logdata; # 記事の数
08: $start_page = $FORM{page}; # 表示する記事の位置

まず、7行目では配列にどれくらいのデータが入っているかの数を取得しています。 Perlの場合、配列は「@〜」という形をとりますが、7行目のようにすることで 配列の数を取得できます。これが記事の件数ですよね?
次に、8行目で表示させるスタートページを決めてます。(これは別にしなくてもかまわないのですが、わかりやすくするためです。)

09: $back_page = $FORM{page}-5; # 戻りのページ
10: if ($back_page < 0){
11:  $back_page = 0;
12: }

次に(上のソース)、 9行目ではページをめくるためのリンクを作るための準備をしています。 ここでは記事を5件ずつ表示させようと考えているため、戻る場合には、つまり 「$back_page」という変数には表示させるべき記事の番号「$FORM{page}」から 5件分を差し引いた数字を入れます。

また、ページがマイナスということはないので、10行目から12行目では マイナスになったときに0以下の数字にならないような処理をしています。

13: $end_page = $FORM{page}+5;
14: if ($end_page > $total_num){
15:  $end_page = $total_num;
16: }

今度は(上のソース)、次のページへの処理です。5件ずつ表示ということで、 現在のページ($FORM{page})に5だけ足した数字を「$end_page」に代入しています。 次のページが記事件数(配列の数)よりも大きくなることはないので、 それ以上にならないように14行目から16行目で調整しています。 (実際はもう少し工夫する必要がありますが・・・)

次からはループ処理になります。(下のソース)
前回から変更になっているのは24行目のところです。 表示させる場所を「$start_page」から「$end_page」までと指定することで 決まった場から決まった件数だけ記事を取り出すことが可能となります。

24: for ($i=$start_page;$i < $end_page;$i++){
25:  # 各行のデータをカンマで区切ってそれぞれの変数へ
26:  ($no,$u_name,$subject,$comment,$date) = split(/\,/,$logdata[$i]);
27:  # ヒアドキュメントによる各記事の生成
28:  print <<"HTML";
29:
30:  ここにHTMLで掲示板の記事を書き出します。
31:
32:  HTML
33: }

以上がページ処理の概要になります。簡単だったでしょうか?データベースを利用して 記事を取り出すならもう少しわかりやすくできるかもしれませんので、 データベースを使える環境にある場合にはデータベースを使ってください。 (いずれ、MySQLなどとの連動も紹介したいと思ってますが・・・)

一つ前にもどる 目次にもどる 次のページへ
(作成2004/12/30 by あいまい)

Valid XHTML 1.0!