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

掲示板(URL自動変換/連続改行・スペース削除)

#! /usr/local/bin/perl

use Jcode;

$FILE        = './dat/board.dat';    #書き込み保存ファイル
$MAX        = 100;            #保存件数
$VIEW        = 10;            #1ページの表示件数
$TEXTMAX    = 1000;            #本文文字数制限(全角)
$NAMEMAX    = 10;            #名前文字数制限(全角)
$TITLEMAX    = 20;            #題名文字数制限(全角)
$PASSWORD    = '1234';        #削除用パスワード
$time        = time;

loadForm();                                #フォームデータ取り込み

loadData();                                #記事データ読み込み

print qq(Content-type: text/html; charset=Shift_JIS\n\n);
print <<END;                                #HTML出力
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    <title>掲示板</title>
    <style type="text/css">
    <!-- 
        body        { padding:10px 5%; background:#eef }
        hr        { display:none }
        form        { margin:5px 0; padding:5px 0; border-bottom:3px solid #f60 }
        table        { margin:20px 5%; width:90%; border:1px solid #963 }
        th        { background:#fc9; text-align:left }
        td        { padding:10px; background:#fff }
        h1        { margin:0px; font-size:22px; border-bottom:3px solid #f60 }
        textarea    { width:80% }
        .small        { font-size:12px; text-align:right }
        .err        { padding:10px 0; color:#f33; font-weight:bolder; text-align:center;
                 border-bottom:3px solid #f60 }
    //-->
    </style>
    <script language="JavaScript">
    <!--
    function check() {                        //空欄・文字数チェック
        for(i = 0 ; i < document.form.length ; i++) {
            with(document.form.elements[i]) {
                if(value == "") {
                    alert("すべての項目を入力してください!!");
                    focus();
                    return false;
                }
                if(name == "text" && value.length > $TEXTMAX) {
                    alert("文字数オーバーです!!(" + value.length + "文字)");
                    focus();
                    return false;
                }
            }
        }
    }
    //-->
    </script>
    </head>
    <body>
    <h1>掲 示 板</h1>
    <hr>
    <form action="$ENV{'SCRIPT_NAME'}" method="POST" name="form" onSubmit="return check()">
    名前:<input type="text" name="name" size="50" maxlength="$NAMEMAX" value="$FORM{'name'}"><br>
    <br>
    題名:<input type="text" name="title" size="50" maxlength="$TITLEMAX"><br>
    <br>
    本文:<textarea name="text" rows="10" cols="70"></textarea><br>
    <small>※$TEXTMAX字以内 ※HTML使用不可(ホームページアドレス・メールアドレスはリンクに自動変換)</small><br>
    <br>
    <input type="hidden" name="mode" value="write">
    <input type="submit" value=" 書き込み "><br>
    </form>
    <hr>
END
if($ERR) {                                #エラーチェック
    print <<"    END";
        <div class="err">【エラー】$ERR!!</div>
        <hr>
    END
}

printData();                                #記事出力

print <<END;                                #HTML出力
    </body>
    </html>
END

exit;


#==============================================================================記事出力
sub    printData
{
    my    $next = $FORM{'next'} + $VIEW;
    if($next > @DATA) {
        $next = @DATA;
    }
    print qq(<form action="$ENV{'SCRIPT_NAME'}" method="POST">\n);
    for($i = $FORM{'next'} ; $i < $next ; ++$i) {
        my    ($tm, $name, $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;    #URL変換
#        $text =~ s/([\w\.\-]+@[\w\.\-]+)/<a href="mailto:$1">$1<\/a>/g;            #メールアドレス変換
        print qq(<table cellspacing="0">);
        print qq(<tr>);
        printf qq(<th><input type="radio" name="no" value="%d">【$title】</th>), $i;
        printf qq(<th class="small">$name [%02d/%02d %02d:%02d]</th>), ++$mon, $date, $hour, $min;
        print qq(</tr>);
#        if($FORM{'pass'} eq $PASSWORD) {
#            print qq(<tr>);
#            print qq(<th colspan="2" class="small">$agent<br>$addr</th>);
#            print qq(</tr>);
#        }
        print qq(<tr>);
        print qq(<td colspan="2">$text</td>);
        print qq(</tr>);
        print qq(</table>\n);
        print qq(<hr>\n);
    }
    print qq(<div align="right">\n);
    print qq(<input type="hidden" name="mode" value="delete">\n);
    print qq(<input type="hidden" name="next" value="$FORM{'next'}">\n);
    print qq(<input type="password" name="pass" value="$FORM{'pass'}" size="4">\n);
    print qq(<input type="submit" value=" 削 除 ">\n);
    print qq(</div>\n);
    print qq(</form>\n);
    print qq(<hr>\n);
    print qq(<center>\n);
    if($FORM{'next'}) {                        #前ページへのリンク
        printf qq(<a href="$ENV{'SCRIPT_NAME'}?next=%d">≪前ページ</a>\n), $FORM{'next'} - $VIEW;
    }
    else {
        print qq(≪前ページ\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;
        }
    }
    if($next < @DATA) {                        #次ページへのリンク
        print qq(<a href="$ENV{'SCRIPT_NAME'}?next=$next">次ページ≫</a>\n);
    }
    else {
        print qq(次ページ≫\n);
    }
    print qq(</center>\n);
}

#==============================================================================読み込み・書き込み・削除
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') {                    #データ追加 
            my    ($tm, $name, $title, $text) = split(/\t/, $DATA[0]);
            if($FORM{'text'} eq "") {
                $ERR = "本文が空白";
                return;
            }
            if(length($FORM{'text'}) > $TEXTMAX * 2
             or length($FORM{'name'}) > $NAMEMAX * 2
             or length($FORM{'title'}) > $TITLEMAX * 2    ){
                $ERR = "文字数オーバー";
                return;
            }
            if($FORM{'text'} eq $text) {
                $ERR = "書き込み済み";
                return;
            }
            unshift @DATA, "$time\t$FORM{'name'}\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 $PASSWORD) {
                $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】