※この記事は9年以上前の記事です。
現在は状況が異なる可能性がありますのでご注意ください。
あぁ、今年ももう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でやろうとしたけど、有効期限などをうまくできなかった・・・。)
これで、世の多くのアクセスカウンターの仕様とだいたい一緒にすることができた。
まぁ、最も、アクセスカウンター自体が懐かしいものなんだけね・・・。
ここ何年かで随分減ったしね。アクセス解析は、アナリィティクスでできるしね・・・。
しかし、いいワークショップになりました。
セキュリティ??
んなもん知るか
コメントする