| アクセスカウンタ |
SSI(Server Side Include)を利用する
このサンプルプログラムはSSIが利用できる場合に有効です。
SSIはHTMLの中に記述され
<!--#exec cgi="/cgi-bin/ssi_count.cgi"--> |
のような形式です。
サーバの種類や設定にもよりますが、HTMLの拡張子は.shtmlにする必要があるかもしれません。あるいはHTMLがあるディレクトリに.htaccessというファイルに設定を記述する場合もあります。
#!/usr/bin/perl
#
# ssi_count.cgi
#
# (C) Kaoru Fujita
#
use lib './lib';
require 'util.pl';
#
# 定数
#
$Title = 'SSIカウンター サンプルプログラム';
$Location = './tmp';
$File = $Location.'/count';
$thePage = $ENV{'DOCUMENT_URI'};
$thePage =~ s/\//_/g; # / を _ に置き換える
$file = "$Location/$thePage.count";
if (-e $file) {
openLock(CNT, "+<$file")
or exitError("ファイル $file がオープンできません。");
$count = <CNT>;
seek(CNT, 0, 0);
}
else {
openLock(CNT, ">$file")
or exitError("ファイル $file が作成できません。");
$count = 0;
}
$count++;
print CNT $count;
closeUnlock(CNT, $file);
print $count;
exit(0);
#--End of ssi_count.cgi
|
<HTML> <HEAD> <TITLE>SSIカウンタ サンプル</TITLE> </HEAD> <BODY> <!--#exec cgi="/cgi-bin/ssi_count.cgi"--> 回目のアクセス </BODY> </HTML> |
[サンプルプログラムの実行]
SSIを利用しない場合
この例は直接CGIを実行する場合です。
#!/usr/bin/perl
#
# count.cgi
#
# (C) Kaoru Fujita
#
use lib './lib';
require 'util.pl';
#
# 定数
#
$Title = 'カウンター サンプルプログラム';
$Location = './tmp';
$File = $Location.'/count';
$CharSet = 'Shift_JIS';
if (-e $File) {
openLock(CNT, "+<$File")
or exitError("ファイル $File がオープンできません。");
$count = <CNT>;
seek(CNT, 0, 0);
}
else {
openLock(CNT, ">$File")
or exitError("ファイル $File が作成できません。");
$count = 0;
}
$count++;
print CNT $count;
closeUnlock(CNT, $File);
while (<DATA>) {
s/__%COUNT%__/$count/;
print;
}
exit(0);
__END__
Content-type: text/html
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=$CharSet">
<TITLE>$Title</TITLE>
</HEAD>
<BODY>
<P>
<CENTER>__%COUNT%__ 回目のアクセスです。</CENTER>
<P>
</BODY>
</HTML>
|
<IMG>タグで画像のアクセスカウンタにする場合
「CGIの起動方法」のところで「HTMLのイメージ<IMG>タグを使って起動する」ことの説明がありますが、この方法を利用します。ただし、カウントの数字の数だけ、CGIが起動されるのでサーバの負荷は大きくなり、表示も遅くなります。また、イメージはブラウザでキャッシングされるので、ほとんどの場合リロードしてもカウントアップしません(ブラウザを一度終了させるとカウントアップします)。
#!/usr/bin/perl
#
# img_count.cgi
#
# (C) Kaoru Fujita
#
use lib './lib';
require 'util.pl';
#
# 定数
#
$Title = 'イメージカウンタ サンプルプログラム';
$Location = './tmp';
$File = $Location.'/img_count';
$ImgLoc = './images';
$ImgType = 'gif';
*data = parseInput();
# テスト用
#$data{'Col'} = '1';
$col = $data{'Col'};
if (-e $File) {
openLock(CNT, "+<$File")
or exitError("ファイル $File がオープンできません。");
$count = <CNT>;
seek(CNT, 0, 0);
}
else {
openLock(CNT, ">$File")
or exitError("ファイル $File が作成できません。");
$count = 0;
}
# 1の位のときだけカウントアップ
$count++ if ($col == 1);
print CNT $count;
closeUnlock(CNT, $File);
@num = split(//, $count); # 各桁を取り出す
@num = reverse(@num); # 桁を配列のインデックスに対応させる
# ために逆順に並べる
# 桁数以上のところは 0 とする
$num = defined($num[$col-1]) ? $num[$col-1] : 0;
sendImage($num);
exit(0);
sub sendImage
{
my($number) = @_;
# イメージファイルのオープン
open(IMG, "$ImgLoc/$number.$ImgType") or
exitError(qq(ファイル $ImgLoc/$number.$ImgType がオープンできません。));
# Windows のようなバイナリとテキストを区別する場合は
# テキストモードでは \r\n が \n に変換されてしまうのを
# 避ける。UNIX では意味がない。
binmode IMG;
binmode STDOUT;
# イメージの出力
print qq(Content-type: image/$ImgType\n\n);
print while (<IMG>);
# イメージファイルのクローズ
close(IMG);
}
#--End of img_count.cgi
|
<HTML> <HEAD> <TITLE>イメージカウンタ</TITLE> </HEAD> <BODY> <IMG SRC="/cgi-bin/img_count.cgi?Col=5"> <IMG SRC="/cgi-bin/img_count.cgi?Col=4"> <IMG SRC="/cgi-bin/img_count.cgi?Col=3"> <IMG SRC="/cgi-bin/img_count.cgi?Col=2"> <IMG SRC="/cgi-bin/img_count.cgi?Col=1"> </BODY> </HTML> |