導入:なぜ今、ファイルベースのカウンターなのか
Webサイトのアクセス数を計測したい場合、通常はMySQLなどのRDBMSを用いるのが一般的です。しかし、小規模なプロジェクトや、データベースを構築するリソースがない環境、あるいは特定のページ単位で軽量に計測したい場合には、ファイルベースのカウンターが非常に有効です。本記事では、外部ライブラリやデータベースを一切使用せず、PHPのファイル操作機能のみで、IPアドレスに基づいた重複排除機能付きのアクセスカウンターを実装する方法を解説します。
基礎知識:ファイルベース管理の仕組み
今回紹介する手法では、主に2つのデータをファイルとして保持します。
1. 訪問者ログ:その日に訪問したユーザーのIPアドレス(ハッシュ化)を記録し、同一人物の重複カウントを防止します。
2. カウンター値:現在の総アクセス数を数値ファイルとして保持します。
これらを「排他制御(flock)」を使って管理することで、同時アクセスが発生しても数値が壊れない堅牢な実装が可能になります。また、IPアドレスをそのまま保存するのはプライバシーの観点から好ましくないため、ソルト(SALT)を用いたMD5ハッシュ化を行い、セキュリティを確保します。
実装:堅牢なアクセスカウンタークラス
以下のサンプルコードは、クラス化された実装です。直近100件のログを保持する仕様により、ファイルサイズを抑えつつ一定期間の重複を排除します。
サンプルプログラム
log_dir = $log_dir;
$this->db_dir = $db_dir;
}
public function log($id) {
// 日付+IPアドレスをハッシュ化
$ip_hash = date(“Ymd_”) . md5(self::SALT . $_SERVER[‘REMOTE_ADDR’]);
$file = $this->log_dir . $id . ‘_’ . md5(self::SALT . $id) . ‘.log’;
$data = [];
$is_new_visitor = true;
// 排他ロックをかけて読み書き
$fp = fopen($file, ‘a+b’);
flock($fp, LOCK_EX);
// 直近100件をチェックして重複を確認
rewind($fp);
while (($line = fgets($fp)) !== false && count($data) < 100) {
if ($ip_hash === trim($line)) {
$is_new_visitor = false;
break;
}
$data[] = trim($line);
}
if ($is_new_visitor) {
// 新規訪問なら先頭にIPハッシュを追加
array_unshift($data, $ip_hash);
ftruncate($fp, 0);
fwrite($fp, implode("\n", array_slice($data, 0, 100)) . "\n");
}
flock($fp, LOCK_UN);
fclose($fp);
return $is_new_visitor ? $this->count_up($id) : $this->get_count($id);
}
private function count_up($id) {
$file = $this->db_dir . $id . ‘_count.log’;
$count = file_exists($file) ? (int)file_get_contents($file) : 0;
$count++;
file_put_contents($file, $count, LOCK_EX);
return $count;
}
public function get_count($id) {
$file = $this->db_dir . $id . ‘_count.log’;
return file_exists($file) ? (int)file_get_contents($file) : 0;
}
}
?>
応用・注意点:現場での運用Tips
実装する上で、以下の点に注意してください。
1. ディレクトリの保護:ログファイルやデータファイルはブラウザから直接閲覧されないよう、必ずドキュメントルートの外に置くか、.htaccessで「deny from all」を設定してください。
2. パーミッション:PHPがファイルを生成・更新できるよう、指定ディレクトリ(log/ および db/)には書き込み権限(Webサーバーユーザー)を付与してください。
3. パフォーマンスの限界:この手法は、極めて高トラフィックなサイトには向きません。大量のアクセスが見込まれる場合は、RedisなどのインメモリDBを利用したカウント方式への切り替えを検討しましょう。
4. プライバシー:IPアドレスのハッシュ化は必須です。ログから個人を特定できないよう、運用上の配慮を徹底してください。
この実装は小規模なポートフォリオサイトや社内ツールでの利用に最適です。ぜひ活用してみてください。