Scrapbook
GitHub概要
matthiasmullie/scrapbook
PHP cache library, with adapters for e.g. Memcached, Redis, Couchbase, APC(u), SQL and additional capabilities (e.g. transactions, stampede protection) built on top.
スター317
ウォッチ9
フォーク27
作成日:2015年9月3日
言語:PHP
ライセンス:MIT License
トピックス
apccachecachingmemcachedphppsr-16psr-6redistransactions
スター履歴
データ取得日時: 2025/10/22 08:07
キャッシュライブラリ
Scrapbook
概要
ScrapbookはPHP用のキャッシュライブラリで、Memcached、Redis、Couchbase、APC(u)、SQLなどの複数のアダプターをサポートし、PSR-6およびPSR-16準拠のキャッシュ機能を提供します。
詳細
Scrapbookは、様々なキャッシュバックエンドに対する統一されたインターフェースを提供するPHPキャッシュライブラリです。レイヤー構造で設計されており、すべてKeyValueStore実装として相互にラップできます。トランザクション、スタンピード保護、バッファリングなどの高度な機能を内蔵し、堅牢性と開発の容易性、スケーラビリティを向上させます。PSR-6(Cache)とPSR-16(SimpleCache)の両方の標準に準拠しており、既存のPHPアプリケーションとの統合が簡単です。Memcached、Redis、SQLite、MySQL、APC、Couchbaseなど幅広いストレージバックエンドをサポートしています。
メリット・デメリット
メリット
- マルチアダプター: Memcached、Redis、SQL、APC など豊富なバックエンド
- PSR準拠: PSR-6およびPSR-16標準に完全準拠
- 高度な機能: トランザクション、スタンピード保護、バッファリング
- レイヤー構造: 機能を組み合わせて柔軟なキャッシュシステムを構築
- 型安全: しっかりとした型チェックとエラーハンドリング
- Composer対応: 簡単なインストールと依存関係管理
デメリット
- PHP専用: 他の言語では使用できない
- 学習コスト: 高度な機能を使うには理解が必要
- バックエンド依存: 選択したストレージの制約を受ける
- 設定複雑性: 複数レイヤーの組み合わせは設定が複雑
主要リンク
書き方の例
基本的な使用方法
<?php
use MatthiasMullie\Scrapbook\Adapters\MemoryStore;
use MatthiasMullie\Scrapbook\Adapters\Memcached;
// メモリストア(開発・テスト用)
$cache = new MemoryStore();
// Memcached の使用
$memcached = new \Memcached();
$memcached->addServer('localhost', 11211);
$cache = new Memcached($memcached);
// 基本操作
$cache->set('key', 'value');
$value = $cache->get('key'); // returns 'value'
$success = $cache->delete('key');
SQLite での使用
<?php
use MatthiasMullie\Scrapbook\Adapters\SQLite;
// SQLite データベース接続
$pdo = new PDO('sqlite:cache.db');
$cache = new SQLite($pdo);
// 基本的なキャッシュ操作
$cache->set('user:123', ['name' => 'John', 'email' => '[email protected]']);
$user = $cache->get('user:123');
// TTL付きでの保存
$cache->set('session:abc', $sessionData, time() + 3600); // 1時間後に期限切れ
Redis での使用
<?php
use MatthiasMullie\Scrapbook\Adapters\Redis;
// Redis接続
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$cache = new Redis($redis);
// 複数の値を一度に設定
$cache->setMultiple([
'product:1' => ['name' => 'Laptop', 'price' => 999],
'product:2' => ['name' => 'Mouse', 'price' => 25],
]);
// 複数の値を一度に取得
$products = $cache->getMultiple(['product:1', 'product:2']);
PSR-6 Cache の使用
<?php
use MatthiasMullie\Scrapbook\Psr6\Pool;
use MatthiasMullie\Scrapbook\Adapters\Redis;
// キャッシュプールの作成
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$cache = new Redis($redis);
$pool = new Pool($cache);
// PSR-6 インターフェースでの操作
$item = $pool->getItem('expensive_operation');
if (!$item->isHit()) {
$result = performExpensiveOperation();
$item->set($result);
$item->expiresAfter(3600); // 1時間後に期限切れ
$pool->save($item);
}
$data = $item->get();
PSR-16 SimpleCache の使用
<?php
use MatthiasMullie\Scrapbook\Psr16\SimpleCache;
use MatthiasMullie\Scrapbook\Adapters\Memcached;
// SimpleCache の作成
$memcached = new \Memcached();
$memcached->addServer('localhost', 11211);
$cache = new Memcached($memcached);
$simpleCache = new SimpleCache($cache);
// シンプルなキャッシュ操作
$value = $simpleCache->get('key', 'default_value');
$simpleCache->set('key', 'new_value', 300); // 5分間キャッシュ
// 複数操作
$values = $simpleCache->getMultiple(['key1', 'key2'], 'default');
$simpleCache->setMultiple(['key1' => 'value1', 'key2' => 'value2'], 600);
バッファリング機能
<?php
use MatthiasMullie\Scrapbook\Buffered\BufferedStore;
use MatthiasMullie\Scrapbook\Adapters\Redis;
// Redis + バッファリング
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$cache = new Redis($redis);
$buffered = new BufferedStore($cache);
// バッファされた操作
$buffered->set('key1', 'value1');
$buffered->set('key2', 'value2');
$buffered->delete('key3');
// すべての操作を一度に実行
$buffered->commit();
トランザクション機能
<?php
use MatthiasMullie\Scrapbook\Adapters\MemoryStore;
$cache = new MemoryStore();
// トランザクション開始
$transaction = $cache->getCollection('transaction');
try {
$transaction->set('user:123', $userData);
$transaction->set('session:abc', $sessionData);
// すべて成功した場合のみコミット
$success = $transaction->commit();
if (!$success) {
throw new Exception('Transaction failed');
}
} catch (Exception $e) {
// エラー時はロールバック
$transaction->rollback();
throw $e;
}
スタンピード保護
<?php
use MatthiasMullie\Scrapbook\Adapters\Redis;
class ExpensiveDataService {
private $cache;
public function __construct() {
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$this->cache = new Redis($redis);
}
public function getExpensiveData($key) {
// キャッシュから取得を試行
$data = $this->cache->get($key);
if ($data === false) {
// ロックを取得してスタンピードを防ぐ
$lock = $this->cache->get($key . ':lock');
if ($lock === false) {
// ロックを設定(短い期間)
$this->cache->set($key . ':lock', true, 30);
try {
// 重い処理を実行
$data = $this->performExpensiveOperation();
// 結果をキャッシュ(長い期間)
$this->cache->set($key, $data, 3600);
} finally {
// ロックを解除
$this->cache->delete($key . ':lock');
}
} else {
// 他のプロセスが処理中の場合は少し待つ
sleep(1);
return $this->getExpensiveData($key);
}
}
return $data;
}
}