本文目录导读:

在 PHP 中实现文件缓存有多种方式,下面介绍几种常见且实用的方法:
简单的文件缓存类
<?php
class FileCache {
private $cacheDir;
private $expireTime;
public function __construct($cacheDir = 'cache/', $expireTime = 3600) {
$this->cacheDir = $cacheDir;
$this->expireTime = $expireTime;
// 创建缓存目录
if (!file_exists($this->cacheDir)) {
mkdir($this->cacheDir, 0755, true);
}
}
// 获取缓存
public function get($key) {
$filename = $this->getFilename($key);
if (!file_exists($filename)) {
return false;
}
// 检查是否过期
if (time() - filemtime($filename) > $this->expireTime) {
$this->delete($key);
return false;
}
$data = file_get_contents($filename);
$data = unserialize($data);
return $data;
}
// 设置缓存
public function set($key, $data) {
$filename = $this->getFilename($key);
$serialized = serialize($data);
return file_put_contents($filename, $serialized);
}
// 删除缓存
public function delete($key) {
$filename = $this->getFilename($key);
if (file_exists($filename)) {
unlink($filename);
return true;
}
return false;
}
// 清除所有缓存
public function clear() {
$files = glob($this->cacheDir . '*');
foreach ($files as $file) {
if (is_file($file)) {
unlink($file);
}
}
}
private function getFilename($key) {
// 使用MD5生成唯一的文件名
return $this->cacheDir . md5($key) . '.cache';
}
}
// 使用示例
$cache = new FileCache('cache/', 3600);
// 检查缓存是否存在
$cachedData = $cache->get('user_profile');
if ($cachedData === false) {
// 从数据库或其他地方获取数据
$userData = ['name' => '张三', 'age' => 25];
// 写入缓存
$cache->set('user_profile', $userData);
$result = $userData;
} else {
$result = $cachedData;
}
print_r($result);
?>
使用正则缓存内容(页面缓存)
<?php
class PageCache {
private $cacheDir;
public function __construct($cacheDir = 'page_cache/') {
$this->cacheDir = $cacheDir;
}
// 开始缓存
public function start($key) {
$filename = $this->getFilename($key);
if (file_exists($filename) && time() - filemtime($filename) < 3600) {
// 读取缓存
echo file_get_contents($filename);
exit; // 结束执行
}
// 开启输出缓冲
ob_start();
$this->currentFile = $filename;
}
// 结束缓存
public function end() {
$content = ob_get_clean();
if (isset($this->currentFile)) {
file_put_contents($this->currentFile, $content);
}
echo $content;
}
private function getFilename($key) {
return $this->cacheDir . md5($key) . '.html';
}
}
// 使用示例
$pageCache = new PageCache();
$pageCache->start('homepage');
// 生成页面内容的代码
echo '<h1>欢迎来到我的网站</h1>';
echo '<p>生成时间: ' . date('Y-m-d H:i:s') . '</p>';
echo '<p>这是一个缓存的页面内容</p>';
$pageCache->end();
?>
使用apc/xcache(如果可用)
<?php
// APC缓存示例(需要启用APC扩展)
if (function_exists('apc_fetch')) {
$key = 'product_100';
$cachedData = apc_fetch($key);
if ($cachedData === false) {
// 获取数据
$data = ['product' => 'iPhone', 'price' => 5999];
apc_store($key, $data, 3600); // 缓存1小时
} else {
$data = $cachedData;
}
}
// 或使用Redis/Memcached(需要扩展支持)
if (class_exists('Redis')) {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$key = 'user_100';
$cachedData = $redis->get($key);
if ($cachedData === false) {
$data = ['name' => '李四', 'age' => 30];
$redis->set($key, json_encode($data), 3600);
} else {
$data = json_decode($cachedData, true);
}
}
?>
使用Composer库(现代方式)
composer require symfony/cache
<?php
require 'vendor/autoload.php';
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cache = new FilesystemAdapter(
$namespace = 'my_app',
$defaultLifetime = 3600,
$directory = 'cache'
);
// 获取缓存项
$products = $cache->getItem('products');
if (!$products->isHit()) {
// 模拟从数据库获取数据
$data = ['product1', 'product2', 'product3'];
$products->set($data);
$cache->save($products);
}
// 获取数据
$result = $products->get();
print_r($result);
?>
实用的缓存函数
<?php
// 简单的函数封装
function cache_get($key, $ttl = 3600) {
$file = 'cache/' . $key . '.php';
if (file_exists($file)) {
$main_file = $file . '.main';
$data = include($file);
// 检查过期时间
if (time() - filemtime($file) < $ttl) {
return $data;
}
}
return null;
}
function cache_set($key, $data) {
$file = 'cache/' . $key . '.php';
$content = '<?php return ' . var_export($data, true) . ';';
return file_put_contents($file, $content);
}
// 使用示例
$key = 'db_query_' . md5('SELECT * FROM users');
$result = cache_get($key);
if ($result === null) {
// 从数据库获取
$result = ['user1', 'user2'];
cache_set($key, $result);
}
print_r($result);
?>
注意事项
- 缓存键设计:使用清晰的缓存键,建议包含功能名称、数据ID等
- 过期时间:根据不同数据设置合理的过期时间
- 缓存目录权限:确保缓存目录可写
- 性能考虑:对于大型应用,考虑使用专业缓存系统(Redis, Memcached)
- 缓存更新:数据更新后要及时清除或更新缓存
- 安全:不要缓存敏感数据,或确保缓存文件目录不可从Web访问
这些方法可以根据你的具体需求选择使用,对于简单的项目,使用基本的文件缓存类即可;对于大型应用,建议使用专业的缓存系统。