Home / Menu

CGI-Perlの基礎講座

CGI-Perlの基礎講座(p02)

(本ページは、KENT WEBのFantasyボードプログラムをステップ単位に説明しています。)

◆ 書きこみ処理(前半)

・概要

ゲストがコメントをテキストエリアに書き込み後、送信(submit)が押された時に実行される処理で、コメントをログファイルに書き込んだりします。

・381から409行目

## --- 書きこみ処理
sub regist {
    # フォーム内容をチェック
    if ($name eq "") { &error("名前が入力されていません。","no"); }
    if ($com eq "") { &error("コメントが入力されていません。","no"); }

ゲストがフォームに書き込んだ必須項目(ゲスト名とコメント)をチェックします。
単なる文字列のイフ文で、入力されていないと & でerrorサブルーチンをコールします。

    # 一時ファイルを定義
    &temp;

ゲストがフォームに書き込んだ必須項目データをトップに持ってくる為の前準備に、予め一時ファイルを作成します。

        # ロック処理
    if ($lockkey == 1) { &lock1; }
    elsif ($lockkey == 2) { &lock2; }

Web上では不特定多数の同時アクセスが有りますので、このゲストブックの実行処理の排他を掛けます。
つまり、これ以降ロック解除されるまでは、お一人様のみ実行で、データの整合性を取ります。
また、ロック方式は2種類用意されています。これは、サーバのperl実装を考慮しての事です。

        open(IN,"$logfile") || &error("Open Error : $logfile","lock");
    $top = <IN>
    ($tno,$tdate,$tname,$tmail,$tarea,$tico,$tico2,$tcom) = split(/<>/, $top);

    if ($name eq "$tname" && $com eq "$tcom") {
        &error("二重投稿は禁止です。","lock");
    }

    # 記事Noを採番
    $no = $tno + 1;

    # ホスト名を取得
    &get_host;

open と split はもうわかりますねぇ。
ここは、現状のログファイルの最新書き込みデータを$topに読み込み($top = <IN>;)、
そして、今回、書き込まれたデータと比較して、二重投稿をチェックしています。
あと、記事Noを採番、書き込んでくれたゲストのホスト名を取得しています。

    # 削除キーを暗号化
    if ($FORM{'pwd'}) { $PW = &make_pwd($FORM{'pwd'}); }

ゲストが削除キーを入力した時に、それを暗号化する為、make_pwdサブルーチンをコールします。
FORMはハッシュ変数で、この場合、削除キーのスカラー値をハッシュ変数から取り出しています。

ハッシュ変数とは、%から始まる変数をいい、スカラー値で参照する時はインデックスに文字列を指定できます。
今回の場合は、削除キーのスカラー値をハッシュ変数から取り出すだけですので、$FORM{'pwd'}のように表現します。

とにかく、リスト、配列変数、ハッシュ変数の概念はperl言語を理解する上で避けて通れません!!
ここで、おさらい致しましょう!!

リストとは、順序付けされた値の集合です。(12 55 8 562.7 や "ヒロ" "ちゃいちゃん" "まちゃ" "やす" 等)
配列とは、値のリストに名前をつけたもの。
配列変数はキーとなるのは整数で、ハッシュ変数はキーとなるのは文字列です。

例、配列変数

@array = (5, 6, 7);

スカラー変数へ代入
$scalar5 = $array[0];
$scalar6 = $array[1];
$scalar7 = $array[2];

例、ハッシュ変数

%array = ("black" => "#000000", "white" => "#FFFFFF");

スカラー変数へ代入
$scalar000000 = $array{"black"};
$scalarFFFFFF = $array{"white"};

配列変数へ代入
@value_list = values %array; ("#000000","#FFFFFF"が格納される)
@key_list = keys %array; ("black","white"が格納される)

◆ 書きこみ処理(後半)

・381から409行目

    open(OUT,">$tmpfile") || &error("Write Error : Temp File","lock");

open(OUT,">$tmpfile")はデータ書き込み専用オーブンです。ちなみに、これ以外は以下があります。
open(OUT,"$tmpfile") または open(OUT,"<$tmpfile")はデータ読み込み専用オープン。
open(OUT,"+<$tmpfile")またはopen(OUT,"+>$tmpfile")はデータ読み込み書き込み両用オープン。
open(OUT,">>$tmpfile")はデータ追加書き込み専用オーブンです。

    print OUT "$no<>$date<>$name<>$email<>$area<>$icon<>$icon2<>$com<><>$url<>$host<>$PW<>\n";
    print OUT "$top";

    $i=0;
    while ($_ = <IN>) {
        $i++;
        if ($i > $max-2) { last; }
        print OUT $_;
    }

    close(OUT);
    close(IN);

一時ファイル(OUT)へ今回の書き込みされた入力データを書き込み、そして、ログファイルの先頭データ($top)を書き込み。
あとは、ログファイルの2番データから$max-2以上になるまで、一時ファイル(OUT)へデータをコピーしています。

    chmod (0666,$tmpfile);
    rename ($tmpfile,$logfile) || &error("Rename Error","lock");

chmod関数で一時ファイルの属性を自分/グループ/他人(0666)すべて読み込み書き込み(フルアクセス)にしています。
0666はここを参照して下さい。
あと、rename関数で一時ファイルをログファイルにしています。(今までのログファイルは亡くなります)

    if (-e $tmpfile) { unlink($tmpfile); }

    # ロック解除
    if (-e $lockfile) { unlink($lockfile); }

上記は各々、指定ファイルが存在すれば(-e ファイル名)、削除(unlink ファイル名)しています。
また、 -e はファイル演算子といって、以下の種類があります。

    -r  : 読み込み可能であれば
    -w  : 書き込み可能であれば
    -x  : 実行可能であれば
    -o  : 自分のものであれば
    -R  : 実uid/gidで読み込み可能であれば
    -W  : 実uid/gidで書き込み可能であれば
    -X  : 実uid/gidで実行可能であれば
    -O  : 実uidのものであれば
    -e  : 存在すれば
    -z  : サイズが0であれば
    -s  : サイズが0でなければ(ファイルサイズを返す)
    -f  : 通常ファイルであれば
    -d  : ディレクトリであれば
    -l  : シンボリックリンクであれば
    -p  : 名前付きパイプであれば
    -S  : ソケットであれば
    -b  : ブロック型スペシャルファイルであれば
    -c  : キャラクタ型スペシャルファイルであれば
    -u  : setuidビットが立っていれば
    -g  : setgifビットが立っていれば
    -k  : stickyビットが立っていれば
    -t  : ファイルハンドルが tty としてオープンされていれば
    -T  : ファイルがテキストファイルであれば
    -B  : ファイルがバイナリファイルであれば
    -M  : perl起動時における、ファイルの更新時刻からの日数
    -A  : perl起動時における、ファイルの参照時刻からの日数
    -C  : perl起動時における、ファイルの作成時刻からの日数
    if ($FORM{'cook'} eq 'on') { &set_cookie; }
    # メール通知処理
    if ($mailing == 1) { &mail_to; }
    elsif ($mailing == 2 && $email ne "$mailto") { &mail_to; }
}

書き込みされた入力データ中にクッキーオン指定があればクッキー設定処理をコールします。
クッキーに関しては、後ほどset_cookie処理でお話ししたいと思います。
あと、書き込み時、メール通知指定があれば、メール通知処理を行います。

Home / Menu