Kazuya Takei
2019-02-16
Laravel JP Conference 2019
あなたは、このスライドの 番目の閲覧者です。
ホームページにアクセスしたときに出てくる、「何人目に訪れたか」がわかるカウンター
サイトの人気具合を図る「スカウター」の一種
たまに壊れる
「キリ番」「踏み逃げ」という文化
アクセス解析の機能がついていたりも
「旧世代の風物詩」感ありますね (要出展)
「忍者カウンター」サービスはいまだ現役でした
リクエストに応じて、
永続化されたデータストアに対して、加算を行い
その数値とベースの絵素材から、表示用画像を作り
画像としてレスポンスを返す
さらにおまけで、
リクエストヘッダなどを元に、人を分類
新規の来訪者
直近の再来訪者
時間経過してかららから来た人
直近の再来訪者だったらカウンターの加算をせずに画像を表示
場合によっては304レスポンスも?
セッション情報を元にしたキャッシュ出し分けを行い
多重アクセスしてもある程度正しく処理できるように、排他処理でカウンターを扱い
画像を結合して、 image/xxx
レスポンスを返す
さらに、Webサービスとして提供するのなら管理画面なども必要
...コンパクトなWebアプリってこういうことを言うのかも
※「自分の実装」と、「探してみた歴史あるアクセスカウンタ」を元にしています
※一例です
- count.php
※一例です
- App/AccessCounter/
- Counters/
- FilesystemCounter.php
- Http/Controllers/
- ShowController.php
- ImageWriters/
- TextSVGImageWriter.php
- GDImageWriter.php
- Tests
- Feature/
- AccessCounter/SessionTest.php
- Unit/
- AccessCounter/CounterTest.php
- AccessCounter/WriterTest.php
fopen
, flock
, fclose
,,,
// fopenでファイルを開き
$fp = fopen('count.data');
// flockで排他処理
flock($fp);
Storage
使うのが楽。(ロックは?)
// Storageのみ
use Storage;
$data = Storage::get('count.dat');
DB
も楽。( Eloquent
も可)
use DB;
$data = DB::where('key', $Key)->lockForUpdate()->get();
$_SERVER['REMOTE_ADDR']
をログにとってチェックする時代もあったかな?
$logs = file('log.dat');
foreach ($logs => $log) {
$host, $timestamp = explode(',', '$log);
if ($host != $_SERVER['REMOTE_ADDR']) {
continue;
}
if ($timestamp + 24*60*60 > time()) {
return false;
}
return true;
}
session
に預かってもらうのはどうでしょう?
// 略
$session = $request->session();
$count = $session->get('access_counter.count', 0);
$timestamp = $session->get('access_counter.timestamp', 0);
if ($timestamp + 24*60*60 > time()) {
return $count;
}
$count = $couner->increment();
return $count;
image関数にお任せ
// 実コード略
// 0.gif 〜 9.gif とかありましたね
SVGというものがありまして。。。
ただし、デザイン力が足りないと辛い
$dom = new \DOMDocument();
$svg = $dom->createElement('svg');
// svgタグの属性足す
$text = $dom->createElement('text', $this->text);
// textタグの属性足す
$svg->appendChild($text);
$dom->appendChild($svg);
return $dom;
アクセスカウンターはWebアプリ
温故知新、楽しい
ご清聴ありがとうございました