スペシャル掲示板

 今回は、今まで実装しなかったクッキー機能と、題名の文字色を投稿者が選択できる機能とを組み込んで見ましょう。そうスペシャルと言う程の事もないんですが、一応一連のスクリプトの中では高機能と言う事で…(^^ゞ

変更部分

 まず記事の書き込み処理の中に、クッキー情報の書き込み処理も追加します。又同時に、スクリプトの最初の辺りで、クッキー情報を読み込む事も忘れないようにしなくてはいけません。

 題名の文字色の変更に関しては、通常通りFORMで書き込んでその値を変数で受け取り、記事の一覧表示の際に処理を施してやります。又ついでに、タグの許可の状況も表示してやる事にしました。ここは至って簡単ですね(^.^)

実際のソース

 では実際のソースを見てみましょう。該当の変更箇所は色を変えて示しています。よく注意してご覧になって下さい。

#!/usr/bin/perl
# ↑あなたが加入しているプロバイダの「perl」言語が使用できるパスを指定します。
# 一般的には「#!/usr/local/bin/perl」か「#!/user/bin/perl」で大丈夫。
require '../jcode.pl';
$bbs_title = 'スペシャル掲示板';
$datafile = 's_keijiban.txt';
$cgi_name = 's_keijiban.cgi'; #ここで使うCGIスクリプトの名前
$max = 100; #記事の最大記憶数
$pageview = 10; #1ページの記事表示数
$passwd = '****'; #管理者用パスワード
$CookieName = 's_keijiban'; #クッキーを格納するクッキー名
#タグの許可 'yes'/'no'
$tag_flag = 'yes';
*クッキーを格納する為のクッキー名を設定します。
#==============初期設定が必要なのはここまでです=================================
($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year += 1900;
$mon = sprintf("%02d", $mon + 1);
$day = sprintf("%02d", $day);
$hour = sprintf("%02d", $hour);
$min = sprintf("%02d", $min);
$date_now = "$year年$mon月$day日 $hour時$min分";
$softagent = $ENV{'HTTP_USER_AGENT'}; #訪問者のブラウザを取得
$hostaddr = &domain_name; #訪問者のホスト名を取得
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $QUERY_DATA, $ENV{'CONTENT_LENGTH'});
} else { $QUERY_DATA = $ENV{'QUERY_STRING'}; }
@pairs = split(/&/,$QUERY_DATA);
foreach $pair (@pairs) {
 ($name, $value) = split(/=/, $pair);
 $value =~ tr/+/ /;
 $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
 $value =~ s/</&lt;/g;
 $value =~ s/>/&gt;/g;
 $value =~ s/\n//g;
 $value =~ s/\,//g;
 &jcode'convert(*value,'sjis');
 $FORM{$name} = $value;
}
#環境変数からクッキー情報をゲット
$cookies = $ENV{'HTTP_COOKIE'};
@pairs = split(/;/,$cookies);
foreach $pair (@pairs) {
 ($name, $value) = split(/=/,$pair);
 $name =~ s/ //g;
 $DUMMY{$name} = $value;
}

#更に、各パーツに分解
@pairs = split(/,/,$DUMMY{$CookieName});
foreach $pair (@pairs) {
 ($name, $value) = split(/\!/,$pair);
 $COOKIE{$name} = $value;
}

#データファイルから記事の読み込み
if (!open(NOTE,"$datafile")) { &error(bad_file); }
@DATA = <NOTE>;
close(NOTE);
*環境変数からクッキー情報を取り込んでいます。まずクッキー全体を取り込み$nameと$valueのペアに分解します。次にそのペアの中から$DUMMY{$CookieName}(フォームから送信した内容)を取り出し、更にこれを分解して$nameと$valueのペアに分解します。実際に書き込みフォーム上に表示する値は、ここで得たクッキー値です。split関数で分解する記号については、クッキーの書き込みの処理部分を見れば一目瞭然です。
if ($FORM{'action'} eq 'delete') {
 if ($FORM{'password'} eq '') { &error(not_pass); }
 if ($FORM{'delcode'} < 1) { &error(bad_code); }
 $i = 0; $match = 0;
 foreach $line (@DATA) {
  ($date,$code,$ress,$name,$email,$HP,$subject,$scolor,$comment,$pass,$host,$agent) = split(/\,/,$line);
  if ($FORM{'delcode'} == $code) {
   if ($FORM{'password'} eq $pass || $FORM{'password'} eq $passwd) {
    splice(@DATA,$i,1);
    $match = 1; last;
   }
  }
  $i++;
 }
 if ($match) {
  if (!open(NOTE,">$datafile")) { &error(bad_file); }
  print NOTE @DATA;
  close(NOTE);
 }
*題名色の値を格納する為に、変数$scolorを追加しています。
} elsif ($FORM{'action'} eq 'regist') {
 if ($FORM{'comment'} ne '') {
  if ($FORM{'name'} eq '') { &error(bad_name); }
  if ($tag_flag eq 'yes') { $FORM{'comment'} = &tag_change($FORM{'comment'}); }
  $count = @DATA;
  if ($count > $max) { pop (@DATA); }
  if ($count < 1) {
   $new_code = 1;
  } else {
   ($date,$code,$ress,$name,$email,$HP,$subject,$scolor,$comment,$pass,$host,$agent) = split(/\,/,$DATA[0]);
   $new_code = $code + 1;
  }
  $value = "$date_now\,$new_code,$FORM{'ress'}\,$FORM{'name'}\,$FORM{'email'}\,$FORM{'HP'}\,$FORM{'subject'}\,$FORM{'scolor'}\,$FORM{'comment'}\,$FORM{'pass'}\,$hostaddr\,$softagent\n";
  unshift(@DATA,$value);
  if (!open(NOTE,">$datafile")) { &error(bad_file); }
  print NOTE @DATA;
  close(NOTE);
*題名色の値を格納する為に、変数$scolorを追加しています。
  #クッキーの書き込み
  $ENV{'TZ'} = "GMT";
  ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst) = localtime(time + 60 * 86400);
  $year += 1900;
  @youbi = ("Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat");
  $mon++;
  $date_gmt = "@youbi[wdy], $day-$mon-$year $hour:$min:$sec GMT";
  $cook = "name\!$FORM{'name'}\,email\!$FORM{'email'}\,HP\!$FORM{'HP'}\,pass\!$FORM{'pass'}";
  print "Set-Cookie: $CookieName=$cook; expires=$date_gmt\n";

 }
}
*クッキー情報を書き込む際の書式については「3.クッキー(Cookie)」のページをご参照下さい。

*クッキーは、グリニッジ標準時(GMT)でのみ保存されます。

*localtime(time + 60 * 86400)・・・「60」は60日の事で、クッキーの保持期間です。「86400」は「24*60*60」で一日の秒数です。

*変数$cookの値の連結には「\!」を使っています。「=」の代わり。
print "Content-type: text/html\n\n";
print "<html><head>\n";
print "<title>" . $bbs_title . "</title></head>\n";
print "<body bgcolor=#FFFFDD text=#000000 link=#FF0000 vlink=#FF0000>\n";
print "<form action=$cgi_name method=POST>\n";
print "<input type=hidden name=action value=regist>\n";
print "<center><font size=6>" . $bbs_title . "</font></center>\n";
print "<center><font size=-1 color='red'>お名前とコメントは、必ずご記入下さい。親記事を削除すると、返信記事も削除されます。尚、記事の最大記録数は100件です。</font></center>\n";
print "<table border=0 cellspacing=1>\n";
print "<tr><td align=right>お名前</td>\n";
print "<td><input type=text size=29 name=name value=$COOKIE{'name'}></td></tr>\n";
print "<tr><td align=right>E-mail</td>\n";
print "<td><input type=text size=29 name=email value=$COOKIE{'email'}></td></tr>\n";
print "<tr><td align=right>HomePage</td>\n";
print "<td><input type=text size=50 name=HP value=$COOKIE{'HP'}></td></tr>\n";
print "<tr><td align=right>題名</td>\n";
#返信の場合は題名を挿入
if ($FORM{'flags'} eq 'return') {
 $FORM{'subject'} =~ s/RE://g; #レスのレスを防ぐ為「RE:」を削除
 print "<td><input type=text size=50 name=subject value=RE:" . $FORM{'subject'} . "></td>\n";
} else { print "<td><input type=text size=50 name=subject></td>\n"; }
print "</tr>\n";
print "<tr><td align=right>題名色</td>\n";
print "<td><input type=radio name=scolor value=#0000ff checked><font color=#0000ff><b>青 </b></font>";
print "<input type=radio name=scolor value=#ff0000><font color=#ff0000><b>赤 </b></font>";
print "<input type=radio name=scolor value=#008000><font color=#008000><b>緑 </b></font>";
print "<input type=radio name=scolor value=#800000><font color=#800000><b>茶 </b></font>";
print "<input type=radio name=scolor value=#800080><font color=#800080><b>紫</b></font>";
print " ▼タグの許可:" . $tag_flag . "</td></tr>\n";

print "<tr><td align=right>コメント</td>\n";
print "<td><textarea name=comment rows=4 cols=60></textarea></td></tr>\n";
print "<tr><td align=right>削除キー</td>\n";
print "<td><input type=password size=10 name=pass value=$COOKIE{'pass'}>\n";
print "<font size=-1 color='red'> *英数8文字以上推奨</font></td></tr>\n";
if ($FORM{'flags'} eq 'return') {
 print "<tr><td></td><td><input type=submit value=「$FORM{'subject'}」へ返信>\n";
 print "<input type=hidden name=ress value=$FORM{'code'}></td></tr>\n";
} else {
 print "<tr><td></td><td><input type=submit value=書き込み>";
 print " <input type=reset value=取り消し></td></tr>\n";
}
print "</table></form>\n";
*題名色を選択してもらう為のラジオボタンを追加しました。又、タグの許可の状態も示しています。

*「お名前」「E-mail」「HomePage」「削除キー」の4ヶ所にクッキー表示を施しています。
foreach $line (@DATA) {
 ($date,$code,$ress,$name,$email,$HP,$subject,$scolor,$comment,$pass,$host,$agent) = split(/\,/,$line);
 $new = 'false';
 if ($ress > 0) { $new = 'true'; }
 if ($new eq 'false') { push(@NEW,$line); }
}
*題名色の値を格納する為に、変数$scolorを追加しています。
if ($FORM{'pline'} eq '') { $pline = 0; } else { $pline = $FORM{'pline'}; }
$end_data = @NEW - 1;
$page_end = $pline + ($pageview - 1);
if ($page_end >= $end_data) { $page_end = $end_data; }
foreach ($pline .. $page_end) {
 ($date,$code,$ress,$name,$email,$HP,$subject,$scolor,$comment,$pass,$host,$agent) = split(/\,/,$NEW[$_]);
*題名色の値を格納する為に、変数$scolorを追加しています。
 $comment = &inline_link($comment);
 $comment =~ s/\r/<br>/g;
 print "<form method=POST action=$cgi_name>\n";
 print "<hr>\n";
 print "[" . $code . "]\n";
 print "<font color=$scolor size=4><b>$subject</b></font>\n";
 if ($email ne "") {
  print "<a href=mailto:$email><strong> $name</strong></a>\n";
 } else { print "<strong> $name</strong>\n"; }
 if ($HP ne "") { print "<a href=$HP target=_top> HomePage</a>\n"; }
 print "<font size=-1> $date</font> <input type=submit value=返信>\n";
 print "<input type=hidden name=flags value=return>\n";
 print "<input type=hidden name=code value=" . $code . ">\n";
 print "<input type=hidden name=subject value=" . $subject . ">\n";
 print "<blockquote>$comment<br><br>\n";
 print "<font size=-1>[$host] $agent</font><br><br>\n";
*題名色の指定に変数$scolorを使っています。
 foreach $ressline (@DATA) {
  ($date2,$code2,$ress2,$name2,$email2,$HP2,$subject2,$scolor2,$comment2,$pass2,$host,$agent) = split(/\,/,$ressline);
  $comment2 = &inline_link($comment2);
  $comment2 =~ s/\r/<br>/g;
  if ($code eq $ress2) {
   print "◆[" . $code2 . "]\n";
   print "<font color=$scolor2><b> $subject2</b></font>\n";
   if ($email2 ne "") {
    print "<a href=mailto:$email2><strong> $name2</strong></a>\n";
   } else { print "<strong> $name2</strong>\n"; }
   if ($HP2 ne "") { print "<a href=$HP2 target=_top> HomePage</a>\n"; }
   print "<font size=-1> $date2</font>\n";
   print "<blockquote>$comment2<br><br>\n";
   print "<font size=-1>[$host] $agent</font></blockquote>\n";
  }
 }
 print "</blockquote></form>\n";
}
*題名色の値を格納する為に、変数$scolor2を追加しています。

*こちらの返信記事でも題名を表示するように変更しました。題名色の指定に変数$scolor2を使っています。
print "<hr>\n";
print "<form method=POST action=$cgi_name>\n";
print "<input type=hidden name=action value=delete>\n";
print "記事番号:<input type=text size=10 name=delcode>";
print " 削除用パスワード:<input type=password size=10 name=password>";
print " <input type=submit value=削除>\n";
print "</form>\n";
$next_line = $page_end + 1;
if ($page_end != $end_data) {
 print "<form method=POST action=$cgi_name>\n";
 print "<input type=hidden name=pline value=$next_line>\n";
 print "<input type=submit value=次のページへ>\n";
 print "</form>\n";
}
print "</body></html>\n";
exit;
#====================訪問者のホスト名を取得するサブルーチン======================
sub domain_name {
 local($addr) = $ENV{'REMOTE_ADDR'};
 local($_) = gethostbyaddr(pack("C4",split(/\./,$addr)),2);
 if ($_ eq '') { $_ = $addr; }
 $_;
}
#===================インラインリンクを有効にするサブルーチン====================
sub inline_link {
 local($_) = $_[0];
 $_ =~ s/([^=^\"]|^)((http|ftp):[!#-9A-~]+)/$1<a href=$2 target=_top>$2<\/a>/g;
 $_ =~ s/([!#-9A-~\-\_]+\@[!#-9A-~\-\_\.]+)/<a href=mailto:$1>$1<\/a>/g;
 $_;
}
#===========================タグを復帰するサブルーチン==========================
sub tag_change {
local($_) = $_[0];
1 while s/(.*)(&lt;(img([!-:A-~\s\=]+))&gt;)/$1<img$4>/i;
1 while s/(.*)(&lt;(font[\s\w\=\#\"\']+)\&gt;(.*)\&lt;\/font\&gt;)/$1<$3>$4<\/font>/i;
1 while s/(.*)(&lt;(b)&gt;(.*)&lt;\/b&gt;)/$1<b>$4<\/b>/i;
1 while s/(.*)(&lt;(i)&gt;(.*)&lt;\/i&gt;)/$1<i>$4<\/i>/i;
1 while s/(.*)(\[\[(.+)\]\])/$1<table border=4><tr><td>$3<\/td><\/tr><\/table>/i;
$_;
}
#================================エラー処理ルーチン=============================
sub error {
$error = $_[0];
if ($error eq "bad_file") { $msg = 'ファイルのオープン、入出力に失敗しました。'; }
elsif ($error eq "bad_name") { $msg = 'お名前が記入されていません。'; }
elsif ($error eq "bad_comment") { $msg = 'コメントが記入されていません。'; }
elsif ($error eq "not_pass") { $msg = 'パスワードが記入されていません。'; }
elsif ($error eq "bad_code") { $msg = '削除記事番号が不正です。'; }
else { $msg = '原因不明のエラーで処理を継続できません。'; }
print "Content-type: text/html\n\n";
print "<html><head><title>" . $bbs_title . "</title></head>\n";
print "<body bgcolor=#FFFFDD text=#000000 link=#FF0000 vlink=#FF0000>\n";
print "<center><h2>エラーです!</h2>\n";
print "やり直して下さい。<hr>\n";
print "<b>" . $msg . "</b></center>\n";
print "</body></html>\n";
exit;
}

*このスクリプトはここのゲストブックと同じです。そちらを見てね(^o^)丿

返信機能付き掲示板 前へ

HOME

次へ フレーム版チャット