個別カウンターは、ユーザーごとにカウントします。
その際、IPアドレスでユーザーを判別しファイル記憶にさせることができますが、
今回はクッキーを使って個別にカウントしていきます。
#!/usr/bin/perl
# クッキー取得
for $tmp (split(/ /,$ENV{"HTTP_COOKIE"})) {
my($name,$val) = split(/=/,$tmp);
# デコード処理
$name =~ s/\%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg;
$val =~ s/\%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg;
$COOKIE{$name} = $val;
}
# カウント
$COOKIE{'COUNT'} += 1;
# クッキー有効期限の日時設定
local($sec,$min,$hour,$mday,$mon,$year,$wday) = gmtime(time+60*24*60*60);
# 月の配列化
@month=('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
# 週の配列化
@week = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
# 有効期限出力形式に変換
$gmt = sprintf("%s, %02d-%s-%04d %02d:%02d:%02d GMT",
$week[$wday],$mday,$month[$mon],$year+1900,$hour,$min,$sec);
# 出力のためエンコード
$out_name = 'COUNT';
$out_value = $COOKIE{'COUNT'};
$out_name =~ s/([^a-zA-Z0-9*\-.\@_ ])/sprintf("%%%02X",ord($1))/eg;
$out_name =~ tr/ /+/;
$out_value =~ s/([^a-zA-Z0-9*\-.\@_ ])/sprintf("%%%02X",ord($1))/eg;
$out_value =~ tr/ /+/;
# クッキーをセット
print "Set-Cookie: $out_name=$out_value; expires=$gmt\n";
print "Content-type: text/html\n\n";
print "あなたは、$COOKIE{'COUNT'}回目のアクセスです。\n";
クッキーの情報は、$ENV{"HTTP_COOKIE"} に格納されており、各データを半角の空白で区切り、
そのデータを=でキーと値にセットされています。
そして、データはエンコードされているのでデコードする必要があります。
しかし、今回のスクリプトでは半角英数字しか取り扱っていないので不要な処理なんですが、形として記述して置きます。
クッキーを%COOKIEへ代入したことによって、 $COOKIE{クッキー名} でクッキーの要素へ参照できるようになります。
今回は、COUNT というキーを使ってカウントしています。
クッキーの保存は、ヘッダー部分へ出力することによってできます。
クッキーの保存形式は "Set_Cookie: クッキー名=値; expires=有効期限\n" となっています。
もし、有効期限を省略した場合は、ブラウザが終了されるまでデータが保持されます。
クッキーへデータを保存する際はエンコードします。
これは、文字コードによる思わぬエラーを避けるためです。
有効期限は、単純に日時を出力するだけでは意味がありません。
決められた形式で出力する必要がありますので、sprintf関数で成型します。
有効期限の形式は "曜日, 日,月,年 時間:分:秒 GMT" となっています。
今回作った個別カウンターは、そのアクセスしたユーザーにしかアクセス回数が表示されません。
管理者がこの数字を把握したい場合は、このクッキーの値をIPアドレスと関連付けてファイルへ保存します。