Kakuuchi(角打ち): 自分が考えうる中でそこそこ現代的な手法・ツールでアクセスカウンタを実装する

タイトルの時点で時代錯誤感がすさまじいですが、今回はアクセスカウンタについてのお話です。

アクセスカウンタといえば、大体1990年代から2000年代にかけて、個人サイトやブログで見かけたであろうアレです。キリ番とかもありましたね。

経緯

経緯としては、PHPフレームワークを使った開発に慣れるために、簡素な作りのプログラムを作りたかったという欲求が以前からあり、そこにたまたま「アクセスカウンタって懐かしいね」という話があったことから「試しに作ってみるか」となった次第です。

成果物

成果物は以下になります。

リポジトリ

デモ

設計・実装・学習

作るに当たってアクセスカウンタの機能を真面目に分解してみます。

  • ユーザが対象ページにアクセス(リクエスト)した際にサーバサイドで数値を1つインクリメントし、インクリメントした値をレスポンスとして返す
    • ブラウザのリロードで徒にカウンタが進まないように何らかの判定処理を持たせる
  • サーバサイドにカウントした数値をデータとして保持する必要がある(永続的なデータストア)

また、今回は下記の条件も加えました。

  • 何かしらのPHPフレームワークを使用する(今回の主目的なので……)
  • カウンタの表示は画像ではなくテキストで(簡略化のため)
  • 累計と本日のカウントを分けて持つ

以上を踏まえて実装を考えます。

バックエンド

  • PHPフレームワーク: Slimを使用
  • データストア(合計のアクセス数、今日のアクセス数): JSON
  • バックエンドはあくまでAPIサーバとして、レスポンスはHTMLやプレーンテキストではなくJSON形式で返却
  • 開発環境用にCORS対応

フロントエンド

  • バックエンドはAPIなので、表示はJavaScriptでHTMLのテキストを書き換えを実施
  • AJAXでAPIからJSONを取得し、その値で書き換える
    • このため、トップページはindex.htmlで良い
  • ブラウザリロードに反応しないようにする判定はWeb Storage(今回はSession Storage)を使用
    • したがって、Session Storageなのでタブやブラウザ自体を閉じて開き直すとインクリメントされる
  • 重複アクセスの場合はGETリクエストのみ、初めてのアクセスの場合はGET+PUTリクエスト

イメージとしては上述のような感じで。リクエスト~レスポンスのフローとしては以下の図のような流れになります。

リクエスト・レスポンスのフロー
リクエスト・レスポンスのフロー

今回はこれに加えて、

バックエンド

  • おおまかですが、バックエンド側の名前空間・ディレクトリ構成はMVC(+ヘルパー)っぽく
  • 名前空間を意識する
  • composerautoloadを使用
  • DIを意識して、クラス間の密結合を避ける
  • PHPUnitによるテストコードを記述する

フロントエンド

  • 今回はjQueryを使用せず、ECMAScript2015ベースで記述
    • JSフレームワークを使ってしまうと通常のWebサイトに埋め込むのが難しくなってしまうのであえてシンプルに

ということを意識しました。

学習という面で見ると

  • Slimの新規学習
  • MVC
  • DI
  • テスト
  • 名前空間の復習
  • CORSの復習

辺りをなるべく念頭に置いて書いてみた形です。

色々足りていない部分はあるかと思いますが、ひとまず形になったので今回記録として残しておきます。

余談

名前はカウンタなのでカウンターテーブルに関係がありそうな事物から名前を取りました。

参考

Slim

slimphp/slim-skeleton

CORS

Monolog

DI

MVC

PHPUnit

JavaScript

Fetch API

Web Storage

アクセスカウンタ

この記事を書いた人

アバター

アルム=バンド

フルスタックエンジニアっぽい何か。LAMPやNodeからWP、gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。