掲示板(年齢・性別・都道府県選択)
#! /usr/local/bin/perl use Jcode; $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=Shift_JIS\n\n); print <<" END"; <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <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 = Jcode::convert($value, 'sjis'); $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; } }
〔 実行する 〕