泰州网络公司 浏览次数:0 发布时间:2026-03-09
PHP 缓存是优化网站性能的核心手段 —— 其本质是将频繁访问、计算 / 查询成本高的内容(如数据库查询结果、渲染好的 HTML 片段 / 整页)暂存到高速存储介质(文件、内存)中,避免重复计算 / 查询,直接返回缓存内容,大幅降低服务器负载、提升响应速度。以下是从「入门级文件缓存」到「企业级 Redis 缓存」的完整 PHP 实现方案,覆盖不同场景的较佳实践。
一、缓存核心原则(先明确方向)
- 缓存目标:优先缓存「读多写少」的内容(如商品列表、文章详情、分类数据),避免缓存高频动态内容(如用户实时余额、验证码);
- 缓存介质选择:
- 小型网站:文件缓存(无需扩展,易实现);
- 中大型 / 高并发网站:Redis/Memcached(内存存储,速度比文件快 10 倍 +);
- 缓存键设计:用唯一标识命名(如
article_123_mobile,包含内容 ID + 设备类型),避免冲突;
- 失效策略:设置合理过期时间,内容更新时主动删除 / 更新缓存(而非等过期)。
二、具体实现方案(从简单到复杂)
1. 入门级:文件缓存(无需扩展,适合小型网站)
文件缓存将数据 / 内容以文件形式存在服务器磁盘,实现简单、无额外依赖,适合流量不大的个人站点 / 小型项目。
(1)封装通用文件缓存函数
php
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg>运行
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <?php
/**
* 文件缓存核心函数:设置/获取/删除缓存
* @param string $key 缓存键(唯一标识)
* @param mixed $data 要缓存的数据(支持数组/字符串)
* @param int $expire 过期时间(秒,默认3600=1小时)
* @return mixed 缓存数据(获取时)/bool(设置/删除时)
*/
class FileCache {
// 缓存存储目录(需确保有读写权限,建议放在非web可访问目录)
private $cacheDir = __DIR__ . '/../cache/';
public function __construct() {
// 初始化缓存目录
if (!is_dir($this->cacheDir)) {
mkdir($this->cacheDir, 0755, true);
}
}
// 生成缓存文件路径
private function getCacheFile($key) {
// 对key做哈希,避免特殊字符问题
$hashKey = md5($key);
return $this->cacheDir . $hashKey . '.cache';
}
// 设置缓存
public function set($key, $data, $expire = 3600) {
$cacheFile = $this->getCacheFile($key);
// 缓存数据包含过期时间+实际内容
$cacheData = [
'expire' => time() + $expire,
'data' => $data
];
// 序列化数据(支持数组)
$content = serialize($cacheData);
// 写入文件(加锁避免并发问题)
$handle = fopen($cacheFile, 'w');
if ($handle) {
flock($handle, LOCK_EX); // 排他锁
fwrite($handle, $content);
flock($handle, LOCK_UN);
fclose($handle);
return true;
}
return false;
}
// 获取缓存
public function get($key) {
$cacheFile = $this->getCacheFile($key);
// 检查文件是否存在且未过期
if (!file_exists($cacheFile) || filemtime($cacheFile) + filesize($cacheFile) < time()) {
$this->delete($key); // 清理过期缓存
return false;
}
// 读取缓存
$content = file_get_contents($cacheFile);
$cacheData = unserialize($content);
// 检查过期时间
if ($cacheData['expire'] < time()) {
$this->delete($key);
return false;
}
return $cacheData['data'];
}
// 删除缓存
public function delete($key) {
$cacheFile = $this->getCacheFile($key);
if (file_exists($cacheFile)) {
return unlink($cacheFile);
}
return true;
}
}
?>
(2)文件缓存使用示例(缓存数据库查询结果)
php
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg>运行
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <?php
// 初始化文件缓存
$fileCache = new FileCache();
// 要缓存的数据库查询:获取文章列表
$cacheKey = 'article_list_page_1'; // 缓存键:文章列表+页码
$articleList = $fileCache->get($cacheKey);
// 缓存未命中:查询数据库并写入缓存
if (!$articleList) {
// 模拟数据库查询(实际项目中替换为PDO/Mysqli查询)
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', '123456');
$stmt = $pdo->query("SELECT id, title, publish_time FROM article LIMIT 10");
$articleList = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 写入缓存,设置过期时间3600秒(1小时)
$fileCache->set($cacheKey, $articleList, 3600);
echo '从数据库获取数据并写入缓存';
} else {
echo '从缓存获取数据';
}
// 输出结果(业务逻辑)
print_r($articleList);
// 当文章更新时,主动删除缓存(关键!避免缓存脏数据)
// $fileCache->delete('article_list_page_1');
?>
2. 进阶:整页缓存(适合准静态页面,如文章详情)
结合输出缓冲(ob_start)缓存整页 HTML,减少 PHP 渲染 + 数据库查询开销,适合访问量高、更新频率低的页面。
php
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg>运行
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <?php
$fileCache = new FileCache();
$articleId = $_GET['id'] ?? 1;
$deviceType = detectDevice(); // 复用之前的设备识别函数
$cacheKey = "article_detail_{$articleId}_{$deviceType}"; // 结合文章ID+设备类型
// 尝试获取整页缓存
$pageContent = $fileCache->get($cacheKey);
if ($pageContent) {
// 直接输出缓存内容
echo $pageContent;
exit;
}
// 缓存未命中:渲染页面
ob_start(); // 开启输出缓冲
?>
<!-- 页面HTML内容(响应式+轻量化) -->
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo htmlspecialchars($article['title']); ?></title>
</head>
<body>
<main>
<h1><?php echo htmlspecialchars($article['title']); ?></h1>
<div class="content"><?php echo $article['content']; ?></div>
</main>
</body>
</html>
<?php
// 获取渲染后的HTML并压缩(复用之前的压缩函数)
$pageContent = compressHtml(ob_get_clean());
// 写入缓存(过期时间设为8小时)
$fileCache->set($cacheKey, $pageContent, 8 * 3600);
// 输出页面
echo $pageContent;
?>
3. 企业级:Redis/Memcached 缓存(高并发场景)
对于中大型网站 / 高并发场景,文件缓存速度不足(磁盘 IO 慢),推荐使用Redis/Memcached(内存存储,响应时间 < 1ms)。
(1)Redis 缓存实现(推荐)
首先确保服务器安装 Redis 扩展:
bash
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg>运行
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> # 安装Redis扩展(PHP7+/8+)
pecl install redis
# 编辑php.ini,添加 extension=redis.so
(2)封装 Redis 缓存类
php
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg>运行
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <?php
/**
* Redis缓存类(支持高并发、分布式)
*/
class RedisCache {
private $redis;
public function __construct() {
$this->redis = new Redis();
// 连接Redis(单机),分布式可使用RedisCluster
$this->redis->connect('127.0.0.1', 6379);
// 如有密码:$this->redis->auth('your_redis_password');
// 选择数据库:$this->redis->select(0);
}
// 设置缓存(支持过期时间)
public function set($key, $data, $expire = 3600) {
// 序列化数组/对象(Redis仅支持字符串/哈希等基础类型)
$serializedData = serialize($data);
return $this->redis->setex($key, $expire, $serializedData);
}
// 获取缓存
public function get($key) {
$data = $this->redis->get($key);
if ($data === false) {
return false;
}
return unserialize($data);
}
// 删除缓存
public function delete($key) {
return $this->redis->del($key);
}
// 批量删除(支持通配符,如article_*)
public function deletePattern($pattern) {
$keys = $this->redis->keys($pattern);
if (!empty($keys)) {
return $this->redis->del($keys);
}
return true;
}
}
?>
(3)Redis 缓存使用示例(缓存热门商品数据)
php
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg>运行
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" style="font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 0px; display: block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"></svg> <?php
$redisCache = new RedisCache();
$cacheKey = 'hot_products_2026'; // 热门商品缓存键
// 获取缓存
$hotProducts = $redisCache->get($cacheKey);
if (!$hotProducts) {
// 数据库查询热门商品(耗时操作)
$pdo = new PDO('mysql:host=localhost;dbname=shop;charset=utf8', 'root', '123456');
$stmt = $pdo->query("SELECT id, name, price FROM product WHERE is_hot=1 LIMIT 20");
$hotProducts = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 写入Redis缓存,过期时间2小时
$redisCache->set($cacheKey, $hotProducts, 7200);
}
// 业务逻辑使用缓存数据
print_r($hotProducts);
// 商品更新时,主动删除缓存
// $redisCache->delete('hot_products_2026');
?>
三、缓存较佳实践(避坑关键)
- 避免缓存穿透:对不存在的数据(如查询 ID=-1 的文章),也缓存一个空值(设置短过期时间,如 60 秒),避免恶意请求打爆数据库;
- 防止缓存击穿:热门 key 过期时,加锁(如 Redis 的 SETNX)避免并发查询数据库;
- 缓存雪崩应对:给不同 key 设置随机过期时间(如 3600±60 秒),避免大量 key 同时过期;
- 主动失效优先:内容更新(如文章编辑、商品调价)时,立即删除对应缓存,而非等过期;
- 监控缓存命中率:通过 Redis 的
INFO stats查看keyspace_hits/keyspace_misses,命中率低于 90% 需优化缓存策略。
四、缓存不适用场景
- 实时性要求极高的内容(如用户实时在线状态、秒杀倒计时);
- 个性化内容(如用户购物车、个人中心);
- 频繁修改的小数据(如计数器,可改用 Redis 自增)。
总结
- 缓存选型:小型网站用文件缓存,中大型 / 高并发用 Redis;
- 核心策略:缓存「读多写少」内容,设置合理过期时间,内容更新时主动删除缓存;
- 性能提升:整页缓存 > 片段缓存 > 数据缓存,优先从顶层(整页)开始缓存,效果更显著。
通过以上缓存方案,PHP 网站的响应时间可从数百毫秒降至几十毫秒,服务器 QPS(每秒请求数)可提升数倍,是低成本高收益的性能优化手段。