□Perl 講座 特別編 > レス

◆レス機能ってどんな処理?

機能を追加するとき、どんな処理が必要なのか?を、よく検討する必要があります。そして今までご紹介してきた事の応用で、殆どのことが出来てしまうんです。大切なのは処理を理解することと、応用できる柔軟性ですね。レスと言っても、投稿記事であったり、名前、E-mailと同じ事なんです。保存してあげて、それを表示すると言うことに変わりありません。
違うのはレスとして別途保存する場所を用意してあげること。また、どの投稿記事のレスなのかの目印をつけること。そして入力・出力のさせ方を決めてあげるだけです。レス機能具体的に各処理について考えていきたいと思います。考える順序として、実際に掲示板を操作するのに必要な順番で考えていきたいと思います。



◆レス機能・追加処理の流れ

1.レスの表示
レスが保存されている場所を作り(読み込み)ます。そしてサブルーチンoutputにレスを表示させる場所を指定しておきます。ここでは、サブルーチンoutputを編集する方法を採用して説明いたします。追加するサブルーチンoutputは記事削除で説明した物を採用します。
#メイン表示プログラム
sub html {

    #ヘッダの読込
    &header;

    #ログの読込
    open(IN,"$file") || &error("Can't open $file");
    @lines = <IN>;
    close(IN);
    #$countの初期化
    $count = 0;

    #ログ全部?
    foreach $line (@lines) {
        local($name,$email,$url,$msr,$res) = split(/<>/,$line);
        #カウント処理
        $count = $count + 1;
        &output;
    }

    #フッタの読込
    &footer;
exit;
}

#リピート部分プログラム
sub output {
    print <<"EOT";
<FORM action="bbs.cgi" method="POST">
<INPUT type="hidden" name="mode" value="delete">
<INPUT type="hidden" name="cnt" value="$count">
投稿者:$name <INPUT type="text" name="pwd" size="10">
<INPUT type="submit" value="削除"><BR>
E-mail:<A href="mailto:$email">$email</A><BR>
Homepage:<A href="$url" target="_blank">$url</A><BR>
投稿内容<BR>
$msr
$res
</FORM>
<HR>
EOT
}
見た目の成型・デザインはご自分で好みに合わせて変更してください。

2.レスを入力するHTML部分の用意
レスを入力するHTML部分を表示させるには大きく別けて2通り考えられます。一つは、投稿記事ごとにレス入力フォームを用意してあげるパターンです。これは、かき’s掲示板Ver.1.0で採用されている方法です。もう一つは検索処理の時にご紹介したように個別にレス入力フォーム画面を用意してあげることです。
投稿記事ごとに入力フォームを用意する場合はサブルーチンoutputを編集、個別のページを用意する場合は新しいサブルーチンを用意する必要があります。
#リピート部分プログラム
sub output {
    print <<"EOT";
<FORM action="bbs.cgi" method="POST">
<INPUT type="hidden" name="mode" value="delete">
<INPUT type="hidden" name="cnt" value="$count">
投稿者:$name <INPUT type="text" name="pwd" size="10">
<INPUT type="submit" value="削除"><BR>
E-mail:<A href="mailto:$email">$email</A><BR>
Homepage:<A href="$url" target="_blank">$url</A><BR>
投稿内容<BR>
$msr
$res
</FORM>
<FORM action="bbs.cgi" method="POST">
<INPUT type="hidden" name="mode" value="res">
<INPUT type="hidden" name="cnt" value="$count">
<INPUT type="text" name="name" size="10">
<INPUT type="text" name="res" size="30">
<INPUT type="submit" value="返信">
</FORM>
<HR>
EOT
}
見た目の成型・デザインはご自分で好みに合わせて変更してください。

3.レスの書き込みルーチンを用意します。
#メインルーチン
&decode;
if ($FORM{'mode'} eq 'write') { &write; }
if ($FORM{'mode'} eq 'res') { &res; } #レス追加用サブルーチン
if ($FORM{'mode'} eq 'delete') { &deletel; } #記事削除
&html;


#レス追加用サブルーチン
sub res {

    #フォームの入力状況確認
    if ($FORM{'name'} eq '') { &error("お名前が入力されていません。"); }
    if ($FORM{'res'} eq '') { &error("メッセージが入力されていません。"); }


    #ファイルのオープン 予め$fileにログファイル名が代入されている物とします。
    open(IN,"$file") || &error("Can't open $file");
    open(OUT,">$temp") || &error("Can't write Temp File");

    #ログファイルを配列@linesに代入
    @lines = <IN>;
    #$countの初期化
    $count = 0;

    foreach $line (@lines) {
        local($name,$email,$url,$msr,$res) = split(/<>/,$line);
        $count = $count + 1;
        #目印が一緒でなければデータを記録
        if ($count != $FORM{'cnt'}) {
            push (@CS,$line);
        }
        else {
            $res =~ s/\n//g; #改行文字削除

            #レス二重書き込み禁止ルーチン
            @RES = split(/<HR>/,$res);
            foreach $RES(@RES) {
                if ($RES eq "返信者:$FORM{'name'}<BR>$FORM{'res'}") {
                 &error("二重書き込み禁止です。");
                }
            }

            $res .= "<HR>返信者:$FORM{'name'}<BR>$FORM{'res'}";
            push (@CS,"$name<>$email<>$url<>$msr<>$res<>\n");

        }
    }

    #ログの書込処理
    print OUT @CS;
    close(OUT);
    close(IN);
    rename($temp,$file) || &error("Rename Error");
    chmod (0666,$file);
    if (-e $temp) { unlink($temp); }

}

一番特徴的な部分は、削除処理のとき、目印$FORM{'cnt'}と$countがイコールだった場合@CSにデータをpushしなかったのに対し、レス作業の場合はレスの部分だけ情報を差し替えてpushしていると言うことです。

説明不足の点は多々あるにせよ(ぉぃ)今まで説明したことをベースにいろいろと試してみてください。実際ほんのちょっとの改造で様々なことが可能になるでしょう。あとはセンスとか発想の問題に・・・。(^-^;;

□特別編 一緒に簡易掲示板を作ってみよう