缓存实战

Redis 教程 · 第 8 章 · 8 次浏览

完整缓存实战:热门文章列表 + 浏览量 + 排行榜,这是 Redis 在网站中最经典的组合拳。

设计

  • 热门列表:Hash 存文章数据,ZSet 存浏览量排行
  • 浏览量:ZINCRBY 实时加分,定期刷回 MySQL
  • 缓存更新:修改时 DEL 让缓存失效,下次查询重建

代码示例

<?php
$redis = new Redis();
$redis->connect("127.0.0.1", 6379);

// 发布文章:写 MySQL + 缓存 Hash + 进排行榜
function publish($pdo, $redis, $id, $title, $content) {
    // MySQL 写入省略...
    $redis->hMSet("post:$id", ["title" => $title, "views" => 0]);
    $redis->zAdd("hot:posts", 0, $id);
}

// 浏览:排行榜 +1,Hash 的 views +1
function view($redis, $id) {
    $redis->zIncrBy("hot:posts", 1, $id);
    $redis->hIncrBy("post:$id", "views", 1);
}

// 查文章:先 Redis,没缓存再查 MySQL 并写回
function get_post($pdo, $redis, $id) {
    $data = $redis->hGetAll("post:$id");
    if (!$data) {
        $row = $pdo->query("SELECT * FROM posts WHERE id=$id")->fetch();
        $redis->hMSet("post:$id", $row);
        return $row;
    }
    return $data;
}

// 热门 TOP10
$ids = $redis->zRevRange("hot:posts", 0, 9);
foreach ($ids as $id) {
    echo $redis->hGet("post:$id", "title"), "<br>";
}
?>
📚 PHP 语法速查
常用条目速查,完整版见对应教程章节。可复制代码到在线运行中测试。
写法 / 语法作用
&lt;?php ... ?&gt;PHP 代码块标记
echo "hello";输出字符串
$name = "张三";变量(以 $ 开头,无需声明类型)
if ($x > 0) { } else { }条件判断
foreach ($arr as $k => $v) { }遍历数组(最常用)
for ($i = 0; $i < 10; $i++) { }计数循环
function fn($a) { return $a; }定义函数
array("a" => 1)关联数组(PHP 的"字典")
count($arr)数组长度
isset($x) / empty($x)变量是否存在 / 是否为空
$_GET["key"] / $_POST["key"]获取表单 / 查询参数
$_SESSION["user"]会话数据读写(需 session_start())
$_COOKIE["key"]读取 Cookie
header("Location: /index.php");页面跳转
mysqli_connect($host, $user, $pass, $db)连接 MySQL(旧接口,新项目用 PDO)
new PDO($dsn, $user, $pass)连接 MySQL(推荐,防 SQL 注入)
$stmt->prepare($sql)预处理语句(防 SQL 注入)
htmlspecialchars($str)HTML 转义(防 XSS)
strlen($s) / mb_strlen($s)字符串长度
explode(",", $s) / implode(",", $arr)字符串拆分 / 拼接
json_encode($arr) / json_decode($s)数组与 JSON 互转
include / require引入文件(require 报错即停)
date("Y-m-d H:i:s")当前时间格式化
$_FILES["file"]文件上传数据
file_put_contents($path, $data)写入文件