カウンターのソースファイル(修正版)
[sourcecode language=”php”]
<?php
// カウントデータとIPアドレスデータのファイルのパス
// count.phpと異なるフォルダに設置するときは変更
$config[‘file’][‘count’] = ‘cnt.php’;
$config[‘file’][‘check’] = ‘ip.php’;
// カウンタの桁数
$config[‘figure’][‘total’] = 6;
$config[‘figure’][‘today’] = 4;
$config[‘figure’][‘yesterday’] = 4;
[/sourcecode]
[php]
<?php
// カウントデータとIPアドレスデータのファイルのパス
// count.phpと異なるフォルダに設置するときは変更
$config[‘file’][‘count’] = ‘cnt.php’;
$config[‘file’][‘check’] = ‘ip.php’;
// カウンタの桁数
$config[‘figure’][‘total’] = 6;
$config[‘figure’][‘today’] = 4;
$config[‘figure’][‘yesterday’] = 4;
// 重複カウント回避時間
// IPアドレスによる同一クライアントの重複カウント回避時間
//
// 設定時間内は同一IPアドレスの重複カウントをしない。
// 単位は分 / (例) 60 を設定すると1時間カウントしない
// 0 を設定すると常にカウントする。
// (IPアドレスの記録もしない。)
$config[‘limit’][‘time’] = 60;
// IPアドレスを記録する上限数
// アクセス時、この記録を参照し、
// 同一IPアドレスで、「重複カウント不許可の時間」内の記録があればカウントしないことになります。
//
// 重複カウント回避時間設定が0の場合IPアドレスの記録・チェックともに行いません。
// 上限を超えた場合、古いリストから順に削除されるので、
// 1時間重複カウントを防止すると仮定した場合、1時間のユニークアクセスと同等以上の上限数を設定すべきです。
// また、上限数を大きくすればするほどチェックに時間がかかり動作は遅延します。
// アクセス状況と動作スピードを検証しつつ適宜設定してください。
$config[‘limit’][‘ip’] = 100;
// カウントデータ取得
if($fp = @fopen($config[‘file’][‘count’],"r+")) {
flock ($fp,LOCK_EX);
$data = fgets($fp);
// データ分割
$datas = divideData($data);
// カウントアップ
if(ipCheck($config)) {
$datas = countUp($datas);
rewind($fp);
ftruncate($fp,fwrite($fp,makeData($datas)));
}
fclose($fp);
// 出力
putCounter($config,$datas);
}
exit;
function putCounter($config,$datas) {
$datas[‘total’] = sprintf("%0".$config[‘figure’][‘total’]."d", $datas[‘total’]);
$datas[‘today’] = sprintf("%0".$config[‘figure’][‘today’]."d", $datas[‘today’]);
$datas[‘yesterday’] = sprintf("%0".$config[‘figure’][‘yesterday’]."d", $datas[‘yesterday’]);
$result=array(
‘total’=> $datas[‘total’],
‘today’=> $datas[‘today’],
‘yesterday’=> $datas[‘yesterday’]
);
$jsonedData = json_encode($result);
$callback="counter";
header("Content-type:text/html;charset=UTF-8");
print $callback . ‘(‘ . $jsonedData . ‘);’;
exit();
}
/** 書込みデータ作成 */
function makeData($datas) {
return join(‘,’,array($datas[‘date’],$datas[‘total’],$datas[‘today’],$datas[‘yesterday’]));
}
/** カウントアップ */
function countUp($datas) {
$date[‘today’] = date("Ymd");
$date[‘yesterday’] = date("Ymd",(time() – 60*60*24));
// データ内の日付検証
if($datas[‘date’] == $date[‘today’]) {
// 今日
$datas[‘today’]++;
}
elseif($datas[‘date’] == $date[‘yesterday’]) {
// 昨日
$datas[‘yesterday’] = $datas[‘today’];
$datas[‘today’] = 1;
}
else {
// 初回等、上記以外
$datas[‘yesterday’] = 0;
$datas[‘today’] = 1;
}
$datas[‘total’]++;
// 日付
$datas[‘date’] = $date[‘today’];
return $datas;
}
/** IPアドレスによる重複カウント防止 */
function ipCheck($config) {
$addr = $_SERVER[‘REMOTE_ADDR’];
// 判定値
$re = 0;
// 今回データ
$current = join(‘,’,array(time(),$addr));
// データバッファ
$buffer = array();
// 時間設定が0の場合、何もしないで1を返す
if($config[‘limit’][‘time’] == 0) {
return 1;
}
// IPデータ取得
$hit = 0;
if($fp = @fopen($config[‘file’][‘check’],"r+")) {
while($line = fgets($fp)){
$line = rtrim($line);
list($old[‘time’],$old[‘ip’]) = explode(‘,’,$line);
if($old[‘ip’] == $addr) {
if($old[‘time’] < time() – ($config[‘limit’][‘time’] * 10)) {
// 同一IPで設定時間外の場合、判定値を1とする
$re = 1;
}
$hit = 1;
}
else {
$buffer[] = $line."n";
}
}
// 同一IPがない場合、判定値を1とする
if($hit == 0) {
$re = 1;
}
// 今回のデータを格納
$buffer[] = $current."n";
sort($buffer);
// 記録上限数に調整
while(count($buffer) > $config[‘limit’][‘ip’]) {
array_shift($buffer);
}
// データ書込み
rewind($fp);
ftruncate($fp,fwrite($fp,join(”,$buffer)));
}
fclose($fp);
return $re;
}
/** データ分割 */
function divideData($data) {
$data = rtrim($data);
if($data) {
list($datas[‘date’],$datas[‘total’],$datas[‘today’],$datas[‘yesterday’]) = explode(‘,’,$data);
}
return $datas;
}
?>
[/php]