かんたん作成【HTML CSS JavaScript PHP CGI Perl Ruby Python .htaccess】

掲示板(年齢・性別・都道府県選択)

#! /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\.\/\-\~\?\=\+\%(&amp;)]+)/<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/&/&amp;/g;
        $value =~ s/</&lt;/g;
        $value =~ s/>/&gt;/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;
    }
}
CGI(Perl)
Hello world ! ユーザーエージェント取得・表示($ENV{'HTTP_USER_AGENT'})
IPアドレス取得・表示($ENV{'REMOTE_ADDR'}) リンク元取得・表示($ENV{'HTTP_REFERER'})
URL取得・表示($ENV{'HTTP_HOST'}, $ENV{'REQUEST_URI'}) 環境変数を全て表示(%ENV)
ホスト名取得・表示(gethostbyaddr) 訪問者のプロバイダーを表示
訪問者の都道府県を取得・表示 日付を表示(localtime time)
日付を画像表示(localtime time, substr) アクセス日時を表示(localtime time)
指定の日までの日数を表示 曜日によって背景色を変える
日によって背景色を変える 月によって背景色を変える
見るたびに背景色を変える 見るたびに背景画像を変える
おみくじ(rand, int) カラーチャート
Shift_JIS文字コード表 UTF-8文字コード表
グラフ(横棒グラフ) アクセスカウンター
アクセスカウンター(画像) アクセスカウンター(今日・昨日)
訪問回数(クッキー, $ENV{'HTTP_COOKIE'}, Set-Cookie) アクセスログ保存
アクセスログ集計 パスワード認証
クッションページ($ENV{'QUERY_STRING'}) クッションページ($ENV{'PATH_INFO'})
フォーム入力内容をクッキーに保存 1つのCGIでフレームページを表示
IPアドレスからホスト名を取得(gethostbyaddr) ホスト名からIPアドレスを取得(gethostbyname)
IPアドレスからプロバイダーを取得 IPアドレスから都道府県を取得
文章中の文字列を別の文字列に一括変換 カレンダー
カレンダー(前月・次月へのリンク付) カレンダー(今年1月〜12月)
掲示板 掲示板(URL自動変換/連続改行・スペース削除)
掲示板(年齢・性別・都道府県選択) 画像アップロード掲示板
チャット Web日記
サイトマップ(ディレクトリ内のファイルを調べる) Webデータ取得(HTTPヘッダー, HTMLソース, use Socket)
Webデータ取得(HTTPヘッダー, HTMLソース, use HTTP::Request::Common) トラックバック受信
トラックバック送信 メール送信(メールフォーム, sendmail)
リバーシ(ボードゲーム) .htaccessユーザー認証用ユーザーファイル作成
リダイレクト 条件指定リダイレクト
言語振り分けリダイレクト 条件指定アクセス拒否(ステータスコードを返す)
HTMLファイル読み込み・表示 HTMLファイル読み込み・パスワード認証
HTMLファイル読み込み・条件指定アクセス拒否 HTMLファイル読み込み・条件指定リダイレクト
外部CGIファイル読み込み(require) 画像ファイル読み込み・表示
画像縮小・拡大・サイズ変更(Image::Magick, Resize) 画像切り出し(Image::Magick, Crop)
画像文字埋め込み(Image::Magick, Annotate) 画像合成(Image::Magick, Composite)
画像生成・保存(Image::Magick->new) 画像合成アクセスカウンター
かんたん作成【HTML CSS JavaScript PHP CGI Perl Ruby Python .htaccess】