ほぷしぃ

Perlによる掲示板の作り方

Perlの基本 /  掲示板に必要な処理 /  文字のデコード /  書き込み処理 /  表示処理 /  エラー処理 /  実行 /  命令 /  環境変数

表示処理

更新日:2005年06月08日

フローチャート(新しいウィンドウで開きます)
この図を見ながら読むと、多少はわかりやすいかと思います。

ファイルの読み込み

まずはLogファイルを読みこみます。
書き込みの時と同じように、ファイルが開けなかったらエラーを表示させるようにします。
そして、開いたファイルを一件ずつに分割していきます。
すると次のように成ります。

  if (!open(OUT, "< $file")) {
    push(@msg,"ファイルの読み込みができませんでした。");
    &error;
  }
  while (<OUT>) {chop; push(@out, $_);}
  close(OUT);

While文の中の<OUT>というのは$_=<OUT>と一緒の事を表していて、意味はOUTから1行ずつ読みこんで$_に格納するという物です。
$_というのは、Perlには命令に変数名を省略できる物があり、省略した場合にはそれぞれに合わせて$_、@_などが対象となります。
この場合1行は文字列なので$_が対象になります。
その読みこんだ1行をchop命令で最後の改行コード(\n)をとり、@outへ格納していきます。

HTMLヘッダの出力

さて、CGIで表示させる時は普通HTMLの形を取ります。そこで、HTMLのヘッダ部分を考えていきます。
printという命令で出力していきます。

print <<"EOT";
  <HTML>
  <HEAD>
  <META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
  <TITLE>$MAIN_TITLE</TITLE>
  </HEAD>
  <BODY>
  <P>$MAIN_TITLE</P>
  <FORM action="bbs.cgi" method="POST">
  <INPUT type="hidden" name="mode" value="write">
  名 前:<INPUT size="20" type="text" name="name"><BR>
  E-mail:<INPUT size="20" type="text" name="mail"><BR>
  URL:<INPUT size="50" type="text" name="home" value="http://"><BR>
  メッセージ:<BR>
  <TEXTAREA rows="5" cols="50" name="text"></TEXTAREA><BR>
  <INPUT type="submit" value="投稿する"><INPUT type="reset" value="クリア">
  </FORM>
  <HR>
EOT

ここで、MAIN_TITLEには掲示板の名前が入っているとします。
Print <<"xxx";〜〜〜〜〜〜〜xxx
というのはxxxからxxxまで出力するという命令で、Plint "〜〜〜";と書いてあるのと一緒です。
1つ目の赤く示した「bbs.cgi」というのはこのcgiのファイル名が入ります。
そして、二つ目の赤く示したところは書き込みなのか読みこみなのかを判断するためにある変数です。
2度目以降にこのCGIを参照するとmodeにはwriteが入っているという事になります。

本文の出力

本文は繰り返し作業になるのでforeach文を使って読み込んだ物が無くなっているところまで繰り返します。
しかし、そのままだと発言数が増えた時にかなり長い間表示されつづけるので、カウンターを作って適当なところで終わらせます。
そして、表示をさせてカウンターがMAXになるか、発言が無くなるまで表示します。

  $num = 0;
  foreach (reverse @out) {
    last if $num == $max;
    $num++;
    ($name,$mail,$home,$text) = split(/<>/);

    print <<"EOT";
      <HR><B>名 前:<A HREF="mailto:$mail">$name</A>
      </B><BR><B>URL:</B><A HREF="$home">
      $home</A><BR><BR>$text\n;
EOT
    exit;
  }

$numというのがカウンターで$maxというのが最大発言数です。この最大発言数は最初のところで指定しておいたものです。
あと、発言が新しい物ほど配列の下に入っているのでreverse関数で1番下の物が1番上に来るように逆順にしています。
ホームページ部分は好きに作ってください。

プログラム

すべてを合わせると、

sub output{
  if (!open(OUT, "< $file")) {
    push(@msg,"ファイルの読み込みができませんでした。");
    &error;
  }
  while (<OUT>) {chop; push(@out, $_);}
  close(OUT);

print <<"EOT";
  <HTML>
  <HEAD>
  <META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
  <TITLE>$MAIN_TITLE</TITLE>
  </HEAD>
  <BODY>
  <P>$MAIN_TITLE</P>
  <FORM action="bbs.cgi" method="POST">
  <INPUT type="hidden" name="mode" value="write">
  名 前:<INPUT size="20" type="text" name="name"><BR>
  E-mail:<INPUT size="20" type="text" name="mail"><BR>
  URL:<INPUT size="50" type="text" name="home" value="http://"><BR>
  メッセージ:<BR>
  <TEXTAREA rows="5" cols="50" name="text"></TEXTAREA><BR>
  <INPUT type="submit" value="投稿する"><INPUT type="reset" value="クリア">
  </FORM>
  <HR>
EOT

  $num = 0;
  foreach (reverse @out) {
    last if $num == $max;
    $num++;
    ($name,$mail,$home,$text) = split(/<>/);

    print <<"EOT";
      <HR><B>名 前:<A HREF="mailto:$mail">$name</A>
      </B><BR><B>URL:</B><A HREF="$home">
      $home</A><BR><BR>$text\n;
EOT
    exit;
  }
}

このようなプログラムになっています。

前のページへ ページのトップへ 次のページへ