のフリーCGI・PHPスクリプトをキーワード、97のカテゴリから検索できます。スクリプトの登録ご利用は一切無料です。


フリー、シェアCGI・PHPスクリプトをキーワード、96のカテゴリから検索できます。

 色々なスクリプトをお探しなら当サイトで検索

  •  フリーのCGI・PHPスクリプトだけをメインに掲載。
  •  ランキングによる評価で人気のスクリプトを紹介。
  •  サンプル(ページ)の閲覧によるダウンロード前の事前評価。
  •  お気に入りスクリプトへのパーソナルリンクの作成。

 スクリプト登録のメリット

  •  フリースクリプトなら一切無料で幾つでも掲載。
  •  細かなカテゴリ(全97項目)で閲覧者に分かり易く分類。
  •  スクリプトを印象づけるサンプル(ページ)の登録が可能。
  •  ダウンロードランキングの実施による人気度の評価。

素材サイト検索
- SPECIAL THANKS -

TOPページFlashを制作して頂きました
[ バナー作成ドットコム ]

簡易掲示板


簡易掲示板は、一言コメントを応用したものですが、今回は書き込みの削除機能を追加してみます。

#!/usr/bin/perl

# コメントデータ
$DATA_BBS = 'bbsdata.cgi';

# IDデータ
$DATA_ID = 'id.dat';

# デコード処理
if($ENV{'REQUEST_METHOD'} eq "POST") {
   read(STDIN, $query, $ENV{'CONTENT_LENGTH'});
} else {
   $query = $ENV{'QUERY_STRING'};
}
@args = split(/&/, $query);
foreach $i (@args) {
   ($name, $val) = split(/=/, $i);
   $name =~ tr/+/ /;
   $name =~ s/%([0-9a-fA-F]{2})/pack('C', hex($1))/eg;
   $val =~ tr/+/ /;
   $val =~ s/%([0-9a-fA-F]{2})/pack('C', hex($1))/eg;
   $in{$name} = $val;
}

# データ読み込み関数
sub Get_BBS {
   open(DATA, "< $DATA_BBS");
   eval{ flock(DATA, 1); };
   @BBS_DATA = <DATA>;
   chomp(@BBS_DATA);
   close(DATA);
}

# データ書き込み関数
sub Set_BBS {
   open(DATA, "+< $DATA_BBS") or open(DATA, ">> $DATA_BBS");
   eval { flock(DATA, 2); };
   seek(DATA, 0, 0);
   foreach(@BBS_DATA) {
      print DATA "$_\n";
   }
   truncate(DATA, tell(DATA));
   close(DATA);
}

# 出力関数
sub Out {
   # データ読み込み
   &Get_BBS();

   print "Content-type: text/html\n\n";

   print <<E_O_M;
<html>
<head>
<title>掲示板</title>
</head>
<body>
E_O_M

   # コメント出力
   foreach(@BBS_DATA) {
      my(@tmp) = split(/\t/);
      # 書き込みの表示と削除用フォームを用意
      print <<E_O_M;
NAME : $tmp[2]<br>
<br>
$tmp[3]<br>
<form action="test.cgi" method="POST">
<input type="password" name="pass" size="10"><input type="submit" value="削除"><br>
<input type="hidden" name="m" value="Del"><input type="hidden" name="id" value="$tmp[0]">
</form>
<hr>
E_O_M
   }

   # 書き込み用フォームの出力
   print <<E_O_M;
<form action="test.cgi" method="POST">
名前 <input type="text" name="name" size="20"><br>
コメント <input type="text" name="comment" size="50"><br>
削除パス <input type="password" name="pass" size="10"><br>
<input type="submit" value="書き込み">
<input type="hidden" name="m" value="In">
</form>
</body>
</html>
E_O_M
}

# 書き込み関数
sub In {
   # データ読み込み
   &Get_BBS();

   # ID取得
   open(DATA, "< $DATA_ID");
   eval{ flock(DATA, 1); };
   $id = <DATA>;
   close(DATA);
   open(DATA, "+< $DATA_ID") or open(DATA, ">> $DATA_ID");
   eval { flock(DATA, 2); };
   seek(DATA, 0, 0);
   print DATA ++$id;
   truncate(DATA, tell(DATA));
   close(DATA);

   push(@BBS_DATA, "$id\t$in{'pass'}\t$in{'name'}\t$in{'comment'}");

   # データの書き込み
   &Set_BBS();

   print "Content-type: text/html\n\n";
   print "書き込みが完了しました!\n";
}

# 書き込み削除関数
sub Del {
   &Get_BBS();

   # データ退避用配列
   my(@new);
   # 削除フラグ
   my($f) = 0;
   foreach(@BBS_DATA) {
      my(@tmp) = split(/\t/);
      # 指定されたIDなら
      if($tmp[0] eq $in{'id'}) {
         # パスワードが一致しならならエラー
         if($tmp[1] ne $in{'pass'}) {
            # 削除失敗
            print "Content-type: text/html\n\n";
            print "パスワードが違います!\n";
            exit;
         }
         $f = 1;
         next;
      }
      # データ退避
      push(@new, $_);
   }
   # 削除フラグが偽ならエラー
   unless($f) {
      # 削除失敗
      print "Content-type: text/html\n\n";
      print "指定されたデータは存在しません!\n";
      exit;
   }
   # 配列上書き
   @BBS_DATA = @new;
   &Set_BBS();
   print "Content-type: text/html\n\n";
   print "削除しました!\n";
}

# モード分岐
if(!$in{'m'}) {
   &Out();
} elsif($in{'m'} eq 'In') {
   &In();
} elsif($in{'m'} eq 'Del') {
   &Del();
}

書き込みの処理やデータの表示などの処理は、一言コメントと対して変わりはありません。
書き込み時にIDの設定が大きく変わったところでしょう。
このIDは、削除するときにその削除の対象となるデータを識別するために使われます。

削除するということは、書き込みデータが複数入っている配列からそのデータのみを削除する方法とります。
今回は、foreach文を用いて処理します。
指定されたIDとデータのIDが一致した場合、削除対象のデータと判別し、削除します。
削除といっても、明示的削除は行っていません。
あらかじめ退避用配列を用意し、そこへ保存するデータをコピーしていきます。
そして、削除するデータが来た場合にはコピーを行いません。
最後に、データ保存用配列を退避用配列で上書きします。
これによって削除処理が完了します。

しかし、この削除方法はデータの量が膨大になると処理が遅くなってきます。
そこで削除方法を下記のように書き換えることもできます。

my($i) = 0;
foreach(@BBS_DATA) {
   my(@tmp) = split(/\t/);
   if($tmp[0] eq $in{'id'}) {
      if($tmp[1] ne $in{'pass'}) {
         # 削除失敗
         print "Content-type: text/html\n\n";
         print "パスワードが違います!\n";
         exit;
      }
      last;
   }
   $i++;
}
# 配列からデータを削除
splice(@BBS_DATA, $i, 1);

この方法と最初に書いた方法の違いは、ループする回数にあります。
最初に書いた方では、最初から最後までループします。つまり、処理に時間がかかってしまいます。
ここで書いたほうでは、削除対象が見つかればループを中断します。

こういう風に、ループする回数を減らすことはサーバーへの負担を減らすことに直結しますので意識しましょう。

sozaiCLUB