本文目录导读:

在 PHP 中更换缓存通常涉及以下几种情况,我来分别说明:
更换缓存驱动/后端
使用缓存抽象层(推荐)
// 以 Laravel 为例,通过配置文件切换
// config/cache.php
'default' => env('CACHE_DRIVER', 'redis'),
// 在 .env 文件中切换
CACHE_DRIVER=redis // 或 file, database, memcached 等
手动实现缓存类切换
interface CacheInterface {
public function get($key);
public function set($key, $value, $ttl = null);
public function delete($key);
}
// Redis 实现
class RedisCache implements CacheInterface {
private $redis;
public function __construct() {
$this->redis = new Redis();
$this->redis->connect('127.0.0.1', 6379);
}
public function get($key) {
return $this->redis->get($key);
}
public function set($key, $value, $ttl = null) {
return $this->redis->set($key, $value, $ttl);
}
public function delete($key) {
return $this->redis->del($key);
}
}
// 文件缓存实现
class FileCache implements CacheInterface {
private $cacheDir;
public function __construct($dir) {
$this->cacheDir = $dir;
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
}
public function get($key) {
$file = $this->cacheDir . '/' . md5($key) . '.cache';
if (file_exists($file)) {
$data = unserialize(file_get_contents($file));
if ($data['expire'] > time()) {
return $data['value'];
}
unlink($file);
}
return null;
}
public function set($key, $value, $ttl = null) {
$file = $this->cacheDir . '/' . md5($key) . '.cache';
$data = [
'value' => $value,
'expire' => time() + ($ttl ?: 3600)
];
return file_put_contents($file, serialize($data));
}
public function delete($key) {
$file = $this->cacheDir . '/' . md5($key) . '.cache';
return file_exists($file) ? unlink($file) : true;
}
}
// 使用工厂模式切换
class CacheFactory {
public static function create($type) {
switch ($type) {
case 'redis':
return new RedisCache();
case 'file':
return new FileCache('/tmp/cache');
default:
throw new Exception("不支持的缓存类型");
}
}
}
// 使用
$cache = CacheFactory::create('redis'); // 或 'file'
$cache->set('user:1', ['name' => 'John'], 3600);
$user = $cache->get('user:1');
清理/刷新缓存
// 清理特定缓存
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->del('user:1');
// 清理所有缓存(Redis)
$redis->flushAll();
// 清理过期缓存(文件缓存)
function cleanExpiredCache($dir) {
$files = glob($dir . '/*.cache');
foreach ($files as $file) {
$data = unserialize(file_get_contents($file));
if ($data['expire'] < time()) {
unlink($file);
}
}
}
缓存失效策略
class CacheManager {
// 版本化缓存键
public static function versionedKey($key) {
$version = self::getCacheVersion();
return "v{$version}:{$key}";
}
// 当需要强制刷新时,更新版本号
public static function invalidateAll() {
$version = time();
file_put_contents('/tmp/cache_version', $version);
return $version;
}
private static function getCacheVersion() {
if (file_exists('/tmp/cache_version')) {
return file_get_contents('/tmp/cache_version');
}
return '1';
}
}
// 使用版本化缓存
$key = CacheManager::versionedKey('users:list');
$users = $cache->get($key);
if ($users === null) {
$users = Database::query('SELECT * FROM users');
$cache->set($key, $users, 3600);
}
实际应用场景示例
// 示例:根据环境切换缓存
class AppCache {
private static $instance = null;
private $driver;
private function __construct() {
$environment = getenv('APP_ENV') ?: 'production';
if ($environment === 'production') {
// 生产环境用 Redis
$this->driver = CacheFactory::create('redis');
} else {
// 开发环境用文件缓存
$this->driver = CacheFactory::create('file');
}
}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function get($key) {
return $this->driver->get($key);
}
public function set($key, $value, $ttl = 3600) {
return $this->driver->set($key, $value, $ttl);
}
}
// 使用
$cache = AppCache::getInstance();
$cache->set('user:profile:1', $profileData, 1800);
最佳实践建议
class CacheHeader {
// 主动设置缓存过期时间
header('Cache-Control: max-age=3600');
header('ETag: "' . md5($content) . '"');
// 检查 ETag (304 Not Modified)
if (isset($_SERVER['HTTP_IF_NONE_MATCH']) &&
$_SERVER['HTTP_IF_NONE_MATCH'] === '"' . $etag . '"') {
http_response_code(304);
exit;
}
}
更换缓存时最重要的几点:
- 统一接口:使用接口或抽象类避免代码大改
- 配置分离:将缓存类型配置放在配置文件或 .env 中
- 版本控制:实现缓存版本控制以便快速失效全部缓存
- 监控告警:添加缓存命中率监控和失败处理