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

画像アップロード掲示板

#! /usr/local/bin/perl

$DIR        = './dat/boardimg/';                    #画像保存フォルダ
$FILE        = './dat/boardimg.dat';                    #書込保存ファイル
$MAX        = 50;                            #保存件数(書込・画像)
$VIEW        = 10;                            #1ページの表示件数
$IMGMAX        = 20 * 1000;                        #画像サイズ制限(バイト)
$TEXTMAX    = 1000;                            #本文文字数制限(全角)
$NAMEMAX    = 10;                            #名前文字数制限(全角)
$TITLEMAX    = 20;                            #題名文字数制限(全角)
$PASSWORD    = '1234';                        #削除用パスワード
$time        = time;

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

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:#efe }
        form        { margin:0px; text-align:left }
        h1        { margin:0px; font-size:20px }
        img        { margin:10px 20px }
        hr        { height:10px; color:#9c9; background:#9c9; border-top:2px solid #393 }
        textarea    { width:80% }
        .err        { color:#f33; font-weight:bolder; text-align:center }
    //-->
    </style>
    </head>
    <body>
    <h1>画像アップロード掲示板</h1>
    <hr>
    <form action="$ENV{'SCRIPT_NAME'}" method="POST" enctype="multipart/form-data">
    名前:<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文字以内</small><br>
    <br>
    画像:<input type="file" name="img" value="" size="50"><br>
    <small>※JPEG・GIFのみ($IMGMAXバイト以内)</small><br>
    <br>
    <input type="hidden" name="mode" value="write">
    <input type="submit" value=" 書き込み "><br>
    </form>
END

open(FILE, "<$FILE") or printError("書込保存ファイルが開けません!!");    #データ読込
eval{ flock(FILE, 1) };
@DATA = <FILE>;
close FILE;

if($FORM{'mode'}) {                            #書込・削除
    #サンプルにつき書き込み停止
    #writeData();
}

printData();                                #記事出力

print <<END;                                #HTML出力
    <hr>
    </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" enctype="multipart/form-data">\n);
    for($i = $FORM{'next'} ; $i < $next ; ++$i) {
        my    ($tm, $name, $title, $text, $img) = split(/\t/, $DATA[$i]);
        my    ($sec, $min, $hour, $date, $mon, $year, $day) = localtime($tm);
        print qq(<hr>\n);
        printf qq(<input type="radio" name="no" value="%d">), $i;
        if($title eq "") {
            $title = "無題";
        }
        print qq(<b>【$title】 $name</b><br>);
        if($img) {
            print qq(<img src="$DIR$img" align="right" alt="$title">);
        }
        print qq($text<br clear="right">);
        printf qq(<div align=right>[%02d/%02d %02d:%02d]</div>), ++$mon, $date, $hour, $min;
    }
    print qq(<hr>\n);
    print qq(<div align="right">\n);
    print qq(<input type="password" name="pass" value="$FORM{'pass'}" size="4">\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="submit" value=" 削 除 ">\n);
    print qq(</div>\n);
    print qq(</form>\n);
    if($FORM{'next'}) {                        #前ページへのリンク
        print qq(<form action="$ENV{'SCRIPT_NAME'}" method="POST" enctype="multipart/form-data">\n);
        printf qq(<input type="hidden" name="next" value="%d">\n), $FORM{'next'} - $VIEW;
        print qq(<input type="submit" value=" ← 前ページ ">\n);
        print qq(</form>\n);
    }
    if($next < @DATA) {                        #次ページへのリンク
        print qq(<form action="$ENV{'SCRIPT_NAME'}" method="POST" enctype="multipart/form-data">\n);
        print qq(<input type="hidden" name="next" value="$next">\n);
        print qq(<input type="submit" value=" 次ページ → ">\n);
        print qq(</form>\n);
    }
}

#==============================================================================書込・削除
sub    writeData
{
    my    $img;
    if($FORM{'mode'} eq 'write') {                    #データ追加 
        if($FORM{'text'} and length($FORM{'text'}) <= $TEXTMAX * 2
                 and length($FORM{'name'}) <= $NAMEMAX * 2
                 and length($FORM{'title'}) <= $TITLEMAX * 2    ) {
            if($FORM{'img'}) {
                $img = writeImg();        #画像アップロード
            }
            unshift @DATA, "$time\t$FORM{'name'}\t$FORM{'title'}\t$FORM{'text'}\t$img\t\n";
            while(@DATA > $MAX) {            #書込保存件数チェック
                deleteImg(@DATA - 1);        #画像削除
                pop @DATA;            #書込削除
            }
            opendir(DIR, $DIR) or printError("画像保存フォルダが開けません!!");
            my    @IMG = readdir(DIR);
            closedir(DIR);
            while(@IMG > $MAX + 2) {        #画像保存枚数チェック
                @IMG = sort @IMG; 
                unlink ($DIR . @IMG[2]);    #画像削除
                splice @IMG, 2, 1;
            }
        }
        else {
            printError("文字数オーバーまたは本文が空白です!!");
        }
    }
    elsif($FORM{'mode'} eq 'delete') {                #データ削除 
        if($FORM{'no'} ne "") {
            if($FORM{'pass'} eq $PASSWORD) {
                deleteImg($FORM{'no'});        #画像削除
                splice @DATA, $FORM{'no'}, 1;    #書込削除
            }
            else {
                printError("削除パスワードが違います!!");
            }
        }
    }
    open(FILE, ">$FILE");                        #データ書き込み
    eval{ flock(FILE, 2) };
    print FILE @DATA;
    close FILE;
}

#==============================================================================画像書込
sub    writeImg
{
    my    @filename    = split(/\./, $FORM{'filename'});
    $filename[@filename - 1] =~ tr/A-Z/a-z/;
    if(length($FORM{'img'}) > $IMGMAX) {
        printError("画像サイズオーバー!! (" . length($FORM{'img'}) . "バイト)");
    }
    elsif($filename[@filename - 1] eq "jpg" or $filename[@filename - 1] eq "gif") {
        my    $img        = $time . "\." . $filename[@filename - 1];
        my    $filename    = $DIR . $img;
        open(IMG1, ">$filename") or printError("ファイル作成に失敗しました!!");
        binmode(IMG1);
        print IMG1 $FORM{'img'};
        close(IMG1);
        return $img;
    }
    else {
        printError("$FORM{'filename'}はアップロードできません!!");
    }
}

#==============================================================================画像削除
sub    deleteImg
{
    my    ($tm, $name, $title, $text, $img) = split(/\t/, $DATA[$_[0]]);
    $img = $DIR . $img;
    if(-e $img) {
        unlink $img;                    
    }
}

#==============================================================================エラー出力
sub    printError
{
    print <<"    END";
        <hr>
        <div class="err">【エラー】$_[0]</div>
    END
    printData();
    print <<"    END";
        <hr>
        </body>
        </html>
    END
    exit;
}

#==============================================================================フォームデータ取込
sub    loadForm
{
    my    ($query, $pair);
    if($ENV{'REQUEST_METHOD'} eq 'POST') {
        read(STDIN, $query, $ENV{'CONTENT_LENGTH'});
    }
    my    ($split) = split(/\x0D\x0A/, $query);
    foreach $pair (split(/$split/, $query)) {
        my    @query = split(/\x0D\x0A/, $pair);
        if($query[1] =~ /name="(\w+)"/) {
            for($i = 3 ; $i < @query ; $i++) {
                if($FORM{$1}) {
                    $FORM{$1} .= "\x0D\x0A";
                }
                $FORM{$1} .= $query[$i];
            }
            if($query[1] =~ /(filename)="(.+\.\w+)"/) {
                $FORM{$1} = $2;
            }
            else {
                $FORM{$1} =~ tr/\t/ /;
                $FORM{$1} =~ tr/</ /;
                $FORM{$1} =~ tr/>/ /;
                $FORM{$1} =~ s/\x0D\x0A/<br>/g;
            }
        }
    }
}
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】