ホームページ >バックエンド開発 >PHPチュートリアル >CF カードのバグ、失血なし、エラー コードなし、PHP キャッシュ実装コードと詳細コメント
コードをコピーします コードは次のとおりです:
class CacheException extends Exception {}
/**
* キャッシュ抽象クラス
*/
abstract class Cache_Abstract {
/**
* キャッシュ変数の読み取り
*
* @param string $key キャッシュの添字
* @returnmixed
*/
abstract public function fetch($key);
/**
* キャッシュ変数
*
* @param string $key キャッシュ変数の添字
* @param string $value キャッシュ変数の値
* @return bool
*/
抽象パブリック関数ストア($key, $value);
/**
* キャッシュ変数を削除します
*
* @param string $key キャッシュインデックス
* @return Cache_Abstract
*/
抽象パブリック関数 delete($key);
/**
* すべてのキャッシュをクリア (削除)
*
* @return Cache_Abstract
*/
抽象パブリック関数 clear();
/**
* ロックキャッシュ変数
*
* @param string $key キャッシュインデックス
* @return Cache_Abstract
*/
抽象パブリック関数ロック($key);
/**
* キャッシュ変数のロック解除
*
* @param string $key キャッシュの添字
* @return Cache_Abstract
*/
抽象パブリック関数unlock($key);
/**
* キャッシュ変数がロックされているかどうかを取得します
*
* @param string $key キャッシュの添字
* @return bool
*/
抽象パブリック関数 isLocked($key);
/**
* ロックされていないことを確認してください
* ロック解除を待機するために最大 $tries 回スリープし、タイムアウトが発生した場合はスキップしてロックを解除します
*
* @param string $key cache subscript
*/
public function checkLock($key) {
if (!$this->isLocked($key)) {
return $this;
}
$ 試行 = 10;
$count = 0;
do {
usleep(200);
$カウント++;
} while ($count isLocked($key)); // 最大做十次睡眠等待機解锁,超時则跳过并解锁
$this->isLocked($key) && $this->unlock($key);
$this を返す;
}
}
/**
* APC 拡張キャッシュ実装
*
*
* @category Mjie
* @package Cache
* @author Liushui Mengchun
* @copyright Copyright (c) 2008-
* @license新しい BSD ライセンス
* @version $Id: Cache/Apc.php バージョン番号 2010-04-18 23:02 cmpan $
*/
class Cache_Apc extends Cache_Abstract {
protected $_prefix = 'cache.mjie.net';
public function __construct() {
if (!function_exists('apc_cache_info')) {
throw new CacheException('apc 拡張機能がインストールされていません');
}
}
/**
* キャッシュ変数の保存
*
* @param string $key
* @parammixed $value
* @return bool
*/
public function store($key, $value) {
return apc_store($this->_storageKey($key), $value);
}
/**
* 読み取りキャッシュ
*
* @param string $key
* @returnmixed
*/
public function fetch($key) {
return apc_fetch($this->_storageKey($key));
}
/**
* キャッシュをクリアします
*
* @return Cache_Apc
*/
パブリック関数 clear() {
apc_clear_cache();
$this を返す;
}
/**
* キャッシュユニットを削除します
*
* @return Cache_Apc
*/
public function delete($key) {
apc_delete($this->_storageKey($key));
$this を返す;
}
/**
* キャッシュユニットがロックされているかどうか
*
* @param string $key
* @return bool
*/
パブリック関数 isLocked($key) {
if ((apc_fetch($this->_storageKey($key) . '.lock')) === false) {
false を返します。
}
true を返します。
}
/**
* キャッシュユニットをロック
*
* @param string $key
* @return Cache_Apc
*/
public function lock($key) {
apc_store($this->_storageKey($key) . '.lock', '', 5);
$this を返す;
}
/**
* キャッシュユニットのロック解除
*
* @param string $key
* @return Cache_Apc
*/
public functionunlock($key) {
apc_delete($this->_storageKey($key) . '.lock');
$this を返す;
}
/**
* 完全なキャッシュ名
*
* @param string $key
* @return string
*/
プライベート関数 _storageKey($key) {
return $this->_prefix . '_' 。 $キー;
}
}
/**
* ファイルキャッシュの実装
*
*
* @category Mjie
* @package Cache
* @author Liushui Mengchun
* @copyright Copyright (c) 2008-
* @license New BSD ライセンス
* @version $Id: Cache/File.php バージョン番号 2010-04-18 16:46 cmpan $
*/
class Cache_File extends Cache_Abstract {
protected $_cachesDir = 'キャッシュ';
パブリック関数 __construct() {
if (define('DATA_DIR')) {
$this->_setCacheDir(DATA_DIR . '/cache');
}
}
/**
* キャッシュ ファイルを取得
*
* @param string $key
* @return string
*/
protected function _getCacheFile($key) {
return $this->_cachesDir . '/' 。 substr($key, 0, 2) 。 '/' 。 $key 。 '.php';
}
/**
* キャッシュ変数を読み取ります
* 情報漏洩を防ぐため、キャッシュファイルの形式は「」で始まるphpファイルです
*
* @param string $key queue subscript
* @returnmixed
*/
public function fetch($key) {
$cacheFile = self::_getCacheFile($key);
if (file_exists($cacheFile) && is_readable($cacheFile)) {
return unserialize(@file_get_contents($cacheFile, false, NULL, 13));
}
false を返します。
}
/**
* キャッシュ変数
* 情報漏洩を防ぐため、キャッシュファイルの形式は「」で始まるphpファイルです
*
* @param string $key キャッシュ変数の添字
* @param string $value キャッシュ変数の値
* @return bool
*/
パブリック関数store($key, $value) {
$cacheFile = self::_getCacheFile($key);
$cacheDir = ディレクトリ名($cacheFile);
if(!is_dir($cacheDir)) {
if(mkdir($cacheDir" target="_blank">!@mkdir($cacheDir, 0755, true)) {
throw new CacheException("キャッシュ ディレクトリを作成できませんでした");
}
}
return @file_put_contents($cacheFile, '' .serialize($value));
}
/**
* キャッシュ変数を削除します
*
* @param string $key キャッシュの添字
* @return Cache_File
*/
public function delete( $key) {
if(emptyempty($key)) {
throw new CacheException("Cache_File::delete() の引数 1 がありません")
}
$cacheFile = self::_getCacheFile($key); ($cacheFile" target="_blank">!@unlink($cacheFile)) {
throw new CacheException("キャッシュ ファイルを削除できませんでした");
}
return $this;
}
/**
* キャッシュユニットがロックされているかどうか
*
* @param string $key
* @return bool
*/
パブリック関数 isLocked($key) {
$cacheFile = self::_getCacheFile($key);
return file_exists($cacheFile . '.lock');
/**
* 锁定
*
* @param string $key
* @return Cache_File
*/
パブリック関数 lock($key) {
$cacheFile = self::_getCacheFile($key);
$cacheDir = dirname($cacheFile);
if(!is_dir($cacheDir)) {
if( mkdir($cacheDir" target="_blank">!@mkdir($cacheDir, 0755, true)) {
if(!is_dir($cacheDir)) {
throw new CacheException("キャッシュ ディレクトリを作成できませんでした");
}
}
}
// 保存ファイルの更新時間と変更時間を設定します
@touch($cacheFile . '.lock');
$this を返す;
}
/**
* 解锁
*
* @param string $key
* @return Cache_File
*/
public functionunlock($key) {
$cacheFile = self::_getCacheFile($key);
@unlink($cacheFile . '.lock');
$this を返す;
}
/**
* ファイルキャッシュディレクトリを設定します
* @param string $dir
* @return Cache_File
*/
保護関数 _setCacheDir($dir) {
$this->_cachesDir = rtrim(str_replace('\', '/', trim($dir)), '/' );
clearstatcache();
if(!is_dir($this->_cachesDir)) {
mkdir($this->_cachesDir, 0755, true);
}
//
$this を返す;
}
/**
* すべてのキャッシュをクリアします
*
* @return Cache_File
*/
public function clear() {
// 遍历目录清除缓存
$cacheDir = $this->_cachesDir;
$d = dir($cacheDir);
while(false !== ($entry = $d->read())) {
if('.' == $entry[0]) {
Continue;
}
$cacheEntry = $cacheDir 。 '/' 。 $エントリー;
if(is_file($cacheEntry)) {
@unlink($cacheEntry);
} elseif(is_dir($cacheEntry)) {
// 保存文件夹有两级
$d2 = dir($cacheEntry);
while(false !== ($entry = $d2->read())) {
if('.' == $entry[0]) {
Continue;
}
$cacheEntry .= '/' 。 $エントリー;
if(is_file($cacheEntry)) {
@unlink($cacheEntry);
}
}
$d2->close();
}
}
$d->close();
$this を返す;
}
}
/**
* キャッシュユニットのデータ構造
* array(
* 'time' => time(), // キャッシュ書き込み時のタイムスタンプ
* 'expire' => $expire, // キャッシュの有効期限
* 'valid' = > true, // キャッシュが有効かどうか
* 'data' => $value // キャッシュされた値
* );*/
final クラス キャッシュ {
/**
* キャッシュの有効期限の長さ (秒)
*
* @var int
*/
private $_expire = 3600;
/**
* キャッシュ処理クラス
*
* @var Cache_Abstract
*/
private $_storage = null;
/**
* @return キャッシュ
*/
static public function createCache($cacheClass = 'Cache_File') {
return new self($cacheClass);
}
プライベート関数 __construct($cacheClass) {
$this->_storage = new $cacheClass();
}
/**
* キャッシュを設定します
*
* @param string $key
* @parammixed $value
* @param int $expire
*/
public function set($key, $value, $expire = false) {
if (!$expire) {
$expire = $this->_expire;
}
$this->_storage->checkLock($key);
$data = array('time' => time(), 'expire' => $expire, 'valid' => true, 'data' => $value);
$this->_storage->lock($key);
{
$this->_storage->store($key, $data); を試してください。
$this->_storage->ロック解除($key);
} catch (CacheException $e) {
$this->_storage->unlock($key);
$e をスローします。
}
}
/**
* 読み取りキャッシュ
*
* @param string $key
* @returnmixed
*/
public function get($key) {
$data = $this->fetch($key);
if ($data && $data['valid'] && !$data['isExpired']) {
return $data['data'];
}
false を返します。
}
/**
* 期限切れや無効なものを含むキャッシュを読み取り、完全なストレージ構造を取得します
*
* @param string $key
*/
public function fetch($key) {
$this->_storage->checkLock($key);
$data = $this->_storage->fetch($key);
if ($data) {
$data['isExpired'] = (time() - $data['time']) > $data['期限切れ'] ?真/偽;
$data を返す;
}
false を返します。
}
/**
* キャッシュを削除します
*
* @param string $key
*/
public function delete($key) {
$this->storage->checkLock($key)
->lock($key)
->delete( $key)
->ロック解除($key);
}
パブリック関数 clear() {
$this->_storage->clear();
}
/**
* キャッシュを無効にする
*
* @param string $key
*/
public function setInvalidate($key) {
$this->storage->checkLock($key)
->lock($key);
try {
$data = $this->_storage->fetch($key);
if ($data) {
$data['valid'] = false;
$this->_storage->store($key, $data);
}
$this->_storage->unlock($key);
} catch (CacheException $e) {
$this->storage->unlock($key);
$e をスローします。
}
}
/**
* キャッシュの有効期限を設定します (秒)
*
* @param int $expire
*/
public function setExpire($expire) {
$this->_expire = (int) $expire;
$this を返します;
}
}
以上、cfpbug の無血無害コードの PHP 保存実行コードと詳細なコメントを紹介しました。これには、cfpbug 無血無害コードに関する内容が含まれており、PHP の教則に関心のある友人の助けになることを望みます。