あぁ、今年ももう9月。4分の3が終わってまった。
いつもならもうか・・・、となりますが、
今年はサイトのリニューアルもできたのでよしとします。
(まだ終わってないって)
さて、サイトのアクセスカウンター、ずっとYahooのジオシティーズのを使ってたのですが、
そのサービスがいつのまにか終了しておりましたので・・・、
自作しました。ええ、しましたとも。
一応、二重カウント防止付き。
仕様としては、同IPは、アクセスから日付変更されるまで、二重カウントしない、です。
(例えば、8月25日にアクセスしたIPは、8月26日00時まで、二重カウントしない・・・って感じ)
というわけで、ソースコードを公開しようかな、とね。さてさて
まずは、下記ファイルを適当にテキストエディタかなんかで作っておく。
・countor.php
・count_no.dat
・first_access_time.dat
・ip_list.dat
とりあえず、全部空でよし。
ファイル名もなんでもよし。
だが、ひとまず、count_no.dat(カウントの数値が入るデータ)には適当に初期数値でも入れておくといい。
0でもいい。
では、スクリプトファイルである、countor.phpの中身を書いていこう。
<?php
//カウンター桁数
define('DIGIT_NO', 7);
//datファイル読み込み
global $countDataFile;
global $firstAccessTimeFile;
global $ipListFile;
$countDataFile = dirname(__FILE__) . '/count_no.dat';
$firstAccessTimeFile = dirname(__FILE__) . '/first_access_time.dat';
$ipListFile = dirname(__FILE__) . '/ip_list.dat';
//IPチェックするかどうか
$doubleCheck = 1;
//ファイルの中身を配列にして変数に格納する。(行ごとに分けられて格納される)
$countData = file($countDataFile);
$firstAccessTimeData = file($firstAccessTimeFile);
$ipListData = file($ipListFile);
//必要データを変数に格納
global $countNo;
global $firstTimeStamp;
global $ipList;
//現在カウントを数値で取得
$countNo = intval($countData[0]);
//その日の最初のアクセス時間を格納する変数宣言
$firstTimeStamp = '';
//タイムdatにタイムが入っていれば、タイムスタンプ格納
if (count($firstAccessTimeData) > 0) {
$firstTimeStamp = $firstAccessTimeData[0];
}
//その日のIPリストの変数と格納
$ipList = array();
if (count($ipListData) > 0) {
$ipList = explode('<>', $ipListData[0]);
}
//今日のタイムスタンプ
$toDay = time();
//24時間後のタイムスタンプを格納
$nextDayBefore = intval($toDay) + 86400;
//年月日を各変数に格納
$nextDayTextYear = date('Y', $nextDayBefore);
$nextDayTextMonth = date('m', $nextDayBefore);
$nextDayTextDay = date('d', $nextDayBefore);
//次の日のテキストを格納 ex)2015-09-03
$nextText = date($nextDayTextYear . '-' . $nextDayTextMonth . '-' . $nextDayTextDay);
//次の日0時のタイムスタンプを取得
$nextDayUsed = strtotime(date($nextText . ' 00:00:00'));
//ファイルに書き込むメソッド
function fileReadFunc($fileUrl, $readText){
$fileOpen = fopen($fileUrl, 'w');
// ファイルロック
flock($fileOpen, LOCK_EX);
if (strlen($readText) > 0) {
//書き込み
fputs($fileOpen, $readText);
} else {
//ファイルを空にする
ftruncate($fileOpen, 0);
}
// ロック解除
flock($fileOpen, LOCK_UN);
// ファイルを閉じる
fclose($fileOpen);
}
//日付変更が行われたかをチェックするフラグ
$dayChange = false;
//一日の初期アクセスを格納
if (strlen($firstTimeStamp) > 0) {
//datにタイムスタンプがある
if ($firstTimeStamp <= $toDay) {
//次の日タイムスタンプより今日のタイムスタンプが大きい
$dayChange = true;
//ファイル書き込み
fileReadFunc($firstAccessTimeFile, $nextDayUsed);
}
} else {
//datファイルに文字列入ってない
$dayChange = true;
//ファイルに書き込み
fileReadFunc($firstAccessTimeFile, $nextDayUsed);
}
//ipListをリセット
if ($dayChange) {
//日付変更が行われていれば、1日のIPアクセスリストをリセット
if (count($ipList) > 0) {
//IPdatに文字列あれば、空にする
fileReadFunc($ipListFile, '');
}
//IPリスト変数をリセット
$ipList = array();
}
//IPリストにIPをいれ、ファイルに書き込むメソッド
function ipPush(){
global $ipList;
global $ipListFile;
//IPリストに、現IPを格納
array_push($ipList, $_SERVER['REMOTE_ADDR']);
$insertIp = implode('<>', $ipList);
//ファイルに書き込み
fileReadFunc($ipListFile, $insertIp);
}
//カウントアップするかのフラグ
$countUP = true;
if (count($ipList) > 0) {
foreach ($ipList as $value) {
if ($_SERVER['REMOTE_ADDR'] == $value) {
//IPリストにあるIPならカウントをしない設定
$countUP = false;
break;
}
}
} else {
//IPリストが空なら、IP追加
ipPush();
}
//最終的なカウンター数値
$nextNo = $countNo;
if ($countUP) {
//カウントアップを実行
$nextNo = $countNo + 1;
fileReadFunc($countDataFile, $nextNo);
if (count($ipList) > 0) {
ipPush();
}
}
echo number_format($nextNo);
して、こいつを表示させたいPHPページから読み込む
<?php
include('/サーバールートからの絶対パス/サイトルートからのディレクトリ/countor.php');
?>
とまぁ、こんな感じ。
だいたいは、コメントを見ていただければわかると思いますが、
二重カウント防止のポイントは、
まずは、最初のアクセスから次の日の00時を取得し、datファイルに書き込み
次にIPリストdatに書き込みし、
それを元に、IPの二重アクセスを防止。
もし日付変更されていたら、IPリストdatファイルを空にする。
こうすれば、その日の間は同IPでは二重カウントはされなく、日付が変更されるとリセットされる。
(最初、ここらをSessionでやろうとしたけど、有効期限などをうまくできなかった・・・。)
これで、世の多くのアクセスカウンターの仕様とだいたい一緒にすることができた。
まぁ、最も、アクセスカウンター自体が懐かしいものなんだけね・・・。
ここ何年かで随分減ったしね。アクセス解析は、アナリィティクスでできるしね・・・。
しかし、いいワークショップになりました。
セキュリティ??
んなもん知るか
コメントする