PHP+MySQL分页实现咨询:代码无报错但不解$current_page作用
关于PHP分页中$current_page的作用及完整实现方案
嘿,我来帮你把这个问题掰扯清楚~首先先给你讲明白$current_page到底是干啥的,再结合你的现有代码把分页功能补全,顺便帮你把原代码里的安全漏洞补上。
一、$current_page的核心作用
简单说,$current_page就是用户当前正在看的页码,它是分页逻辑的核心:
- 当你设置每页显示10条数据(也就是你的
$page_size=10),如果用户看第2页,那数据库需要从第11条数据开始取,这个起始位置的计算就靠它:起始位置 = ($current_page - 1) * $page_size - 它还用来控制分页导航栏的高亮显示,让用户清楚自己当前在第几页
- 同时能帮你做边界校验,比如用户手动输入一个超大的页码,你可以用它把页码限制在总页数范围内
二、结合你的代码完善分页功能
你的原代码里缺少$current_page的处理,还有直接拼接用户输入的SQL注入风险,我帮你把完整的分页逻辑补全了,代码里加了详细注释:
<?php // 数据库连接 $con = mysqli_connect("localhost", "root", "", "dbdb") or die("连接错误"); mysqli_set_charset($con, "utf8"); // 设置字符集,避免中文乱码 // 分页基础配置 $page_size = 10; // 每页显示10条数据 $page_list_size = 10; // 分页栏最多显示10个页码 // 处理当前页码$current_page // 优先从URL的GET参数获取页码,没有的话默认显示第1页 $current_page = isset($_GET['page']) ? (int)$_GET['page'] : 1; $current_page = max($current_page, 1); // 确保页码不会小于1 // 处理搜索逻辑(修复SQL注入风险) $valueTosearch = ''; $where_condition = ''; if (isset($_POST['search']) && !empty(trim($_POST['valueTosearch']))) { $valueTosearch = trim($_POST['valueTosearch']); // 用占位符代替直接拼接,防止SQL注入 $where_condition = " WHERE CONCAT(`Ship_Date`,`Model_No`,`Serial_No`) LIKE ?"; } // 计算总数据条数,用来算总页数 $count_sql = "SELECT COUNT(*) AS total_rows FROM `shipment` {$where_condition}"; $count_stmt = mysqli_prepare($con, $count_sql); if (!empty($valueTosearch)) { $search_param = "%{$valueTosearch}%"; mysqli_stmt_bind_param($count_stmt, "s", $search_param); } mysqli_stmt_execute($count_stmt); $count_result = mysqli_stmt_get_result($count_stmt); $total_rows = mysqli_fetch_assoc($count_result)['total_rows']; mysqli_stmt_close($count_stmt); // 计算总页数,ceil()用来向上取整(比如总11条数据,每页10条,总页数就是2) $total_pages = ceil($total_rows / $page_size); $current_page = min($current_page, $total_pages); // 确保页码不会超过总页数 // 计算当前页数据的起始位置 $start_position = ($current_page - 1) * $page_size; // 获取当前页的数据 $data_sql = "SELECT * FROM `shipment` {$where_condition} ORDER BY Ship_Date DESC LIMIT ?, ?"; $data_stmt = mysqli_prepare($con, $data_sql); // 动态绑定参数(根据是否有搜索条件来调整) $params = []; $param_types = ""; if (!empty($valueTosearch)) { $params[] = "%{$valueTosearch}%"; $param_types .= "s"; // s代表字符串类型 } $params[] = $start_position; $param_types .= "i"; // i代表整数类型 $params[] = $page_size; $param_types .= "i"; // 绑定并执行查询 mysqli_stmt_bind_param($data_stmt, $param_types, ...$params); mysqli_stmt_execute($data_stmt); $data_result = mysqli_stmt_get_result($data_stmt); // 输出当前页的数据(这里你可以改成自己的HTML格式) while ($row = mysqli_fetch_assoc($data_result)) { echo "发货日期:{$row['Ship_Date']} | 型号:{$row['Model_No']} | 序列号:{$row['Serial_No']}<br><hr>"; } mysqli_stmt_close($data_stmt); mysqli_close($con); // 生成分页导航栏 echo "<div style='margin-top:20px;'>"; // 上一页按钮 if ($current_page > 1) { echo "<a href='?page=" . ($current_page - 1) . "' style='margin:0 5px;'>← 上一页</a>"; } // 页码列表 $start_page = max(1, $current_page - floor($page_list_size / 2)); $end_page = min($total_pages, $start_page + $page_list_size - 1); for ($i = $start_page; $i <= $end_page; $i++) { if ($i == $current_page) { // 当前页码高亮显示 echo "<span style='padding:3px 8px; background:#007bff; color:white; border-radius:3px;'>{$i}</span>"; } else { echo "<a href='?page={$i}' style='margin:0 5px;'>{$i}</a>"; } } // 下一页按钮 if ($current_page < $total_pages) { echo "<a href='?page=" . ($current_page + 1) . "' style='margin:0 5px;'>下一页 →</a>"; } echo "</div>"; ?>
三、几个关键注意点
- SQL注入防护:原代码直接把用户输入的
$valueTosearch拼进SQL里,非常危险,我改成了预处理语句,用占位符代替直接拼接,能有效防止注入攻击 - 页码边界控制:用
max()和min()限制$current_page的范围,避免出现0页、负数页或者超过总页数的情况 - 用GET传递页码:分页参数用GET的话,用户可以直接复制链接分享当前页,用POST的话刷新页面会弹出重新提交表单的提示,体验不好
内容的提问来源于stack exchange,提问作者Edwin
相关产品推荐
相关产品推荐

