掲示板(年齢・性別・都道府県選択)
#! /usr/local/bin/perl
$FILE = './dat/board3.dat'; #書き込み保存ファイル
$MAX = 100; #保存件数
$VIEW = 10; #1ページの表示件数
$NAMEMAX = 10; #名前文字数制限(全角)
$TITLEMAX = 20; #題名文字数制限(全角)
$TEXTMAX = 1000; #本文文字数制限(全角)
$PASS = '1234'; #削除用パスワード
@COLOR1 = ("ff9999", "99ff99", "9999ff");
@COLOR2 = ("ffcccc", "ccffcc", "ccccff");
@SEI = ("男性", "女性");
@KEN = ( "北海道", "青森", "秋田", "岩手", "山形", "宮城", "福島",
"栃木", "茨城", "群馬", "千葉", "埼玉", "東京", "神奈川",
"山梨", "静岡", "長野", "新潟",
"富山", "石川", "福井",
"愛知", "岐阜", "三重",
"滋賀", "奈良", "京都", "和歌山", "大阪", "兵庫",
"岡山", "広島", "鳥取", "島根", "山口",
"香川", "愛媛", "徳島", "高知",
"福岡", "大分", "長崎", "佐賀", "宮崎", "熊本", "鹿児島",
"沖縄" );
$time = time; #日時取得
loadForm(); #フォームデータ取り込み
loadData(); #記事データ読み込み・書き込み・削除
printHead();
if($ERR) {
printErr(); #エラーメッセージ表示
}
printData(); #記事表示
printInput(); #入力フォーム表示
printEnd();
exit;
#==============================================================================記事表示
sub printData
{
my $next = $FORM{'next'} + $VIEW;
if($next > @DATA) {
$next = @DATA;
}
for($i = $FORM{'next'} ; $i < $next ; ++$i) {
my ($tm, $name, $age, $sei, $ken, $title, $text, $agent, $addr) = split(/\t/, $DATA[$i]);
my ($sec, $min, $hour, $date, $mon, $year, $day) = localtime($tm);
if($title eq "") {
$title = "無題";
}
# $text =~ s/(http:\/\/[\w\.\/\-\~\?\=\+\%(&)]+)/<a href="$1">$1<\/a>/g;
# $text =~ s/([\w\.\-]+@[\w\.\-]+)/<a href="mailto:$1">$1<\/a>/g;
print qq(<table cellspacing="0" width="98%" align="center" bgcolor="#)
. $COLOR1[$i % @COLOR1] . qq(">);
print qq(<tr>);
print qq(<th align="left"><font size="-1">$title</font><br></th>);
print qq(</tr>);
print qq(<tr>);
print qq(<td bgcolor="#) . $COLOR2[$i % @COLOR2]
. qq("><font size="-1">$text</font><br></td>);
print qq(</tr>);
print qq(<tr>);
printf qq(<td class="small" align="right" bgcolor="#) . $COLOR2[$i % @COLOR2]
. qq("><font size="-1">$name \($KEN[$ken] $age歳 $SEI[$sei]\)<br>[%02d/%02d %02d:%02d]</font><br></td>),
++$mon, $date, $hour, $min;
print qq(</tr>);
if($FORM{'pass'} eq $PASS) {
print qq(\n<tr>);
print qq(<td>);
print qq(<form action="$ENV{'SCRIPT_NAME'}" method="POST">\n);
print qq(<input type="hidden" name="mode" value="delete">\n);
printf qq(<input type="hidden" name="no" value="%d">\n), $i;
printf qq(<input type="hidden" name="tm" value="%d">\n), $tm;
print qq(<input type="hidden" name="next" value="$FORM{'next'}">\n);
print qq(<input type="hidden" name="pass" value="$FORM{'pass'}">\n);
print qq(<input type="submit" value=" 削 除 ">\n);
print qq(</form>\n);
print qq(</td>);
print qq(</tr>);
}
print qq(</table>\n);
print qq(<hr>\n);
}
print qq(<center>\n);
print qq(<font size="-1">\n);
if($FORM{'next'}) {
printf qq(<a href="$ENV{'SCRIPT_NAME'}?next=%d">≪前ページ</a>\n), $FORM{'next'} - $VIEW;
}
else {
print qq(≪前ページ\n);
}
if($next < @DATA) {
print qq(<a href="$ENV{'SCRIPT_NAME'}?next=$next">次ページ≫</a>\n);
}
else {
print qq(次ページ≫\n);
}
print qq(<br>\n);
for($i = 0 ; $i < @DATA ; $i += $VIEW) {
if($i == $FORM{'next'}) {
printf qq(%d\n), $i / $VIEW + 1;
}
else {
printf qq(<a href="$ENV{'SCRIPT_NAME'}?next=$i">%d</a>\n), $i / $VIEW + 1;
}
}
print qq(</font>\n);
print qq(</center>\n);
print qq(<br><br>\n);
}
#==============================================================================
sub printHead
{
print qq(Content-type: text/html; charset=UTF-8\n\n);
print <<" END";
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
<!--
body { margin:0px;padding:3px; }
h1 { margin:0px;color:#999;font-size:22px;border-bottom:3px solid #ccc; }
hr { display:none; }
form { margin:0;padding:0; }
table { margin:20px 5%;width:90%;border:1px solid #333; }
th { padding:5px;text-align:left; }
td { padding:10px;background:#fff; }
textarea { width:80%; }
.err { padding:10px 0;color:#f33;font-weight:bolder;
text-align:center;border-bottom:3px solid #ccc;}
//-->
</style>
<title>掲示板</title>
</head>
<body>
<h1>掲 示 板</h1>
<hr>
END
}
#==============================================================================
sub printEnd
{
print <<" END";
</body>
</html>
END
}
#==============================================================================エラーメッセージ表示
sub printErr
{
print <<" END";
<div class="err">【エラー】$ERR!!</div>
<hr>
END
}
#==============================================================================入力フォーム
sub printInput
{
my ($i);
print <<" END";
<table width="98%" align="center" bgcolor="#cccccc">
<tr>
<td bgcolor="#ffffff">
<form action="$ENV{'SCRIPT_NAME'}" method="POST">
<font size="-1">
名前:<small>※$NAMEMAX字以内</small><br>
<input type="text" name="name" size="50" maxlength="$NAMEMAX" value="$FORM{'name'}"><br>
年齢:<br>
<select name="age">
END
for($i = 10 ; $i < 100 ; $i++) {
print qq(<option value="$i");
if($i == $FORM{'age'} or (!($FORM{'age'}) and $i == 25)) {
print qq( selected);
}
print qq(>$i歳</option>\n);
}
print <<" END";
</select><br>
性別:<br>
<select name="sei">
END
for($i = 0 ; $i < @SEI ; $i++) {
print qq(<option value="$i");
if($i == $FORM{'sei'}) {
print qq( selected);
}
print qq(>$SEI[$i]</option>\n);
}
print <<" END";
</select><br>
都道府県:<br>
<select name="ken">
END
for($i = 0 ; $i < @KEN ; $i++) {
print qq(<option value="$i");
if($i eq $FORM{'ken'} or (!($FORM{'ken'}) and $i == 12)) {
print qq( selected);
}
print qq(>$KEN[$i]</option>\n);
}
print <<" END";
</select><br>
題名:<small>※$TITLEMAX字以内</small>
<br><input type="text" name="title" size="50" maxlength="$TITLEMAX"><br>
本文:<small>※$TEXTMAX字以内</small><br>
<textarea name="text" rows="15" cols="70"></textarea><br>
<center>
<input type="hidden" name="mode" value="write">
<input type="submit" value=" 書き込み ">
</center>
</font>
</form>
</td>
</tr>
</table>
<br><br>
END
}
#==============================================================================読み込み・書き込み・削除
sub loadData
{
open(FILE, "<$FILE") or ($ERR = "記事ファイルが開けません" and return);
eval{ flock(FILE, 1) };
@DATA = <FILE>;
close FILE;
if($FORM{'mode'}) {
if($FORM{'mode'} eq 'write') {
if($FORM{'text'} eq ""
or $FORM{'name'} eq ""
or $FORM{'title'} eq "" ){
$ERR = "空欄があります";
return;
}
if(length($FORM{'text'}) > $TEXTMAX * 2
or length($FORM{'name'}) > $NAMEMAX * 2
or length($FORM{'title'}) > $TITLEMAX * 2 ){
$ERR = "文字数オーバー";
return;
}
my ($tm, $name, $age, $sei, $ken, $title, $text) = split(/\t/, $DATA[0]);
if($FORM{'text'} eq $text) {
$ERR = "書き込み済み";
return;
}
unshift @DATA,
"$time\t$FORM{'name'}\t$FORM{'age'}\t$FORM{'sei'}\t$FORM{'ken'}\t$FORM{'title'}\t$FORM{'text'}\t"
. "$ENV{'HTTP_USER_AGENT'}\t$ENV{'REMOTE_ADDR'}\t\n";
while(@DATA > $MAX) {
pop @DATA;
}
}
elsif($FORM{'mode'} eq 'delete') {
if($FORM{'no'} eq "") {
return;
}
if($FORM{'pass'} ne $PASS) {
$ERR = "削除パスワードが違います";
return;
}
my ($tm) = split(/\t/, $DATA[$FORM{'no'}]);
if($FORM{'tm'} ne $tm) {
$ERR = "削除するデータが見つかりません";
return;
}
splice @DATA, $FORM{'no'}, 1;
}
#サンプルにつき書き込み停止
#open(FILE, ">$FILE");
#eval{ flock(FILE, 2) };
#print FILE @DATA;
#close FILE;
}
}
#==============================================================================フォームデータ取り込み
sub loadForm
{
my ($query, $pair);
if($ENV{'REQUEST_METHOD'} eq 'POST') {
read(STDIN, $query, $ENV{'CONTENT_LENGTH'});
}
else {
$query = $ENV{'QUERY_STRING'};
}
foreach $pair (split(/&/, $query)) {
my ($key, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg;
$value =~ s/&/&/g;
$value =~ s/</</g;
$value =~ s/>/>/g;
$value =~ s/\x81\x40/ /g; #全角スペースを半角スペースに変換
$value =~ s/(\s*\x0D\x0A\s*)+/<br>/g; #改行を<br>に変換(前後のスペース・連続改行削除)
$value =~ s/\s+/ /g; #連続スペースをスペース1文字に変換
if($value eq "<br>" or $value eq " ") { #改行・スペースのみの場合 削除
$value = "";
}
if(substr($value, 0, 4) eq "<br>") { #先頭が改行の場合 削除
$value =~ s/<br>//;
}
$FORM{$key} = $value;
}
}
〔 実行する 〕