在PHP分页场景中,用户手动调整每页显示条数后,希望后续切换分页、刷新页面时都能保持之前设置的条数,而不是每次都恢复默认值,这就需要实现每页条数的记忆功能。

实现核心逻辑
记忆每页条数的核心思路分为三步:
- 用户提交修改每页条数的请求时,将新的条数存储到持久化容器中
- 分页请求触发时,优先从持久化容器中读取已存储的条数
- 如果容器中没有存储的条数,再使用预设的默认条数,同时保证条数在合理范围内
使用Cookie实现记忆功能
Cookie是存储在客户端的方案,适合不需要服务端存储、用户本地记忆的场景,即使用户关闭浏览器,只要Cookie未过期,下次访问时仍能读取到之前的设置。
完整实现代码
<?php
// 默认每页条数
$defaultPageSize = 10;
// 允许的每页条数范围
$allowPageSizes = [5, 10, 20, 50];
// 处理用户提交的条数修改请求
if (isset($_POST['page_size'])) {
$inputSize = intval($_POST['page_size']);
// 校验条数是否在允许范围内
if (in_array($inputSize, $allowPageSizes)) {
// 设置Cookie,有效期30天
setcookie('page_size', $inputSize, time() + 86400 * 30, '/');
// 立即生效,避免当前请求读不到新Cookie
$_COOKIE['page_size'] = $inputSize;
}
}
// 获取当前每页条数:优先读Cookie,没有则用默认值
if (isset($_COOKIE['page_size']) && in_array(intval($_COOKIE['page_size']), $allowPageSizes)) {
$pageSize = intval($_COOKIE['page_size']);
} else {
$pageSize = $defaultPageSize;
}
// 模拟分页数据,假设总数据量为100条
$totalCount = 100;
// 获取当前页码,默认第一页
$currentPage = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
// 计算偏移量
$offset = ($currentPage - 1) * $pageSize;
// 模拟查询当前页数据
$currentData = array_slice(range(1, $totalCount), $offset, $pageSize);
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>PHP分页条数记忆(Cookie版)</title>
</head>
<body>
<h3>调整每页显示条数</h3>
<form method="post" action="">
<select name="page_size" onchange="this.form.submit()">
<?php foreach ($allowPageSizes as $size): ?>
<option value="<?php echo $size; ?>" <?php if ($size == $pageSize) echo 'selected'; ?>>
<?php echo $size; ?>条/页
</option>
<?php endforeach; ?>
</select>
</form>
<h3>当前页数据(每页<?php echo $pageSize; ?>条)</h3>
<ul>
<?php foreach ($currentData as $item): ?>
<li>数据项:<?php echo $item; ?></li>
<?php endforeach; ?>
</ul>
<h3>分页导航</h3>
<?php
$totalPage = ceil($totalCount / $pageSize);
for ($i = 1; $i <= $totalPage; $i++) {
if ($i == $currentPage) {
echo "<strong>$i</strong> ";
} else {
echo "<a href='?page=$i'>$i</a> ";
}
}
?>
</body>
</html>
使用Session实现记忆功能
Session是存储在服务端的方案,适合需要用户登录、条数设置和用户账号绑定的场景,用户退出登录后,Session失效,下次登录需要重新设置。
完整实现代码
<?php
// 开启Session
session_start();
// 默认每页条数
$defaultPageSize = 10;
// 允许的每页条数范围
$allowPageSizes = [5, 10, 20, 50];
// 处理用户提交的条数修改请求
if (isset($_POST['page_size'])) {
$inputSize = intval($_POST['page_size']);
if (in_array($inputSize, $allowPageSizes)) {
// 存储到Session中
$_SESSION['page_size'] = $inputSize;
}
}
// 获取当前每页条数:优先读Session,没有则用默认值
if (isset($_SESSION['page_size']) && in_array(intval($_SESSION['page_size']), $allowPageSizes)) {
$pageSize = intval($_SESSION['page_size']);
} else {
$pageSize = $defaultPageSize;
}
// 模拟分页数据,假设总数据量为100条
$totalCount = 100;
// 获取当前页码,默认第一页
$currentPage = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
// 计算偏移量
$offset = ($currentPage - 1) * $pageSize;
// 模拟查询当前页数据
$currentData = array_slice(range(1, $totalCount), $offset, $pageSize);
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>PHP分页条数记忆(Session版)</title>
</head>
<body>
<h3>调整每页显示条数</h3>
<form method="post" action="">
<select name="page_size" onchange="this.form.submit()">
<?php foreach ($allowPageSizes as $size): ?>
<option value="<?php echo $size; ?>" <?php if ($size == $pageSize) echo 'selected'; ?>>
<?php echo $size; ?>条/页
</option>
<?php endforeach; ?>
</select>
</form>
<h3>当前页数据(每页<?php echo $pageSize; ?>条)</h3>
<ul>
<?php foreach ($currentData as $item): ?>
<li>数据项:<?php echo $item; ?></li>
<?php endforeach; ?>
</ul>
<h3>分页导航</h3>
<?php
$totalPage = ceil($totalCount / $pageSize);
for ($i = 1; $i <= $totalPage; $i++) {
if ($i == $currentPage) {
echo "<strong>$i</strong> ";
} else {
echo "<a href='?page=$i'>$i</a> ";
}
}
?>
</body>
</html>
两种方案对比
| 对比项 | Cookie方案 | Session方案 |
|---|---|---|
| 存储位置 | 客户端浏览器 | 服务端内存/存储 |
| 有效期 | 可自定义,关闭浏览器仍有效 | 会话期间有效,关闭浏览器或退出登录失效 |
| 适用场景 | 无需登录的公共页面、本地偏好设置 | 需要登录的私有页面、用户绑定设置 |
| 安全性 | 较低,客户端可修改 | 较高,客户端无法直接修改 |
注意事项
- 无论使用哪种方案,都需要对用户输入的条数做校验,避免传入非法值导致查询异常
- 如果使用Cookie方案,需要注意Cookie的大小限制,不要存储过多内容
- 如果项目是多服务器部署,使用Session方案需要配置Session共享,避免不同服务器读取不到Session数据
- 条数修改后建议立即刷新当前分页,避免用户需要手动切换分页才能看到效果