如何使用PHP和SQL实现每达到指定输入数量自动生成分页?
实现方案
1. 数据库表设计
首先创建存储用户提交记录的表,结构参考如下:
CREATE TABLE `upload_records` ( `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `message` varchar(255) NOT NULL COMMENT '用户留言', `file_path` varchar(255) NOT NULL COMMENT '上传文本文件的存储路径', `created_at` datetime NOT NULL DEFAULT current_timestamp() COMMENT '提交时间' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
自增ID和提交时间字段用于后续排序,实现最新提交内容优先展示在首页的效果。
2. 上传提交逻辑
核心PHP提交处理代码示例,可单独存为submit.php:
<?php if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['text_file']) && isset($_POST['message'])) { // 基础文件格式校验 $allowed_ext = ['txt']; $file_ext = pathinfo($_FILES['text_file']['name'], PATHINFO_EXTENSION); if (!in_array(strtolower($file_ext), $allowed_ext)) { die('仅支持上传txt格式文本文件'); } // 生成唯一文件名避免覆盖 $save_name = uniqid() . '.' . $file_ext; $save_path = '/你的自定义上传目录/' . $save_name; if (move_uploaded_file($_FILES['text_file']['tmp_name'], $save_path)) { // 写入数据库 $pdo = new PDO('mysql:host=你的数据库地址;dbname=你的库名;charset=utf8mb4', '数据库用户名', '数据库密码'); $stmt = $pdo->prepare("INSERT INTO upload_records (message, file_path) VALUES (?, ?)"); $stmt->execute([trim($_POST['message']), $save_path]); // 提交成功跳转回第一页 header('Location: /index.php?page=1'); exit; } die('文件上传失败,请检查目录权限'); } ?>
记得给上传目录设置正确读写权限,生产环境可额外增加文件大小限制、内容敏感词过滤等校验规则。
3. 分页查询核心逻辑
这部分是实现?page=参数分页的核心,写在列表展示页(例如index.php):
<?php // 每页展示的记录条数,按需调整为你需要的10条 $per_page = 10; // 获取当前页码,非法值默认返回第1页 $current_page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1; // 计算SQL查询偏移量 $offset = ($current_page - 1) * $per_page; // 连接数据库 $pdo = new PDO('mysql:host=你的数据库地址;dbname=你的库名;charset=utf8mb4', '数据库用户名', '数据库密码'); // 查询总记录数计算总页数 $total_stmt = $pdo->query("SELECT COUNT(*) FROM upload_records"); $total_records = $total_stmt->fetchColumn(); $total_pages = ceil($total_records / $per_page); // 页码合法性校验,超过总页数自动跳转到最后一页 if ($current_page > $total_pages && $total_pages > 0) { header('Location: ?page=' . $total_pages); exit; } // 查询当前页的记录,按提交时间倒序,最新内容排在最前 $list_stmt = $pdo->prepare("SELECT * FROM upload_records ORDER BY created_at DESC LIMIT ? OFFSET ?"); $list_stmt->bindValue(1, $per_page, PDO::PARAM_INT); $list_stmt->bindValue(2, $offset, PDO::PARAM_INT); $list_stmt->execute(); $record_list = $list_stmt->fetchAll(PDO::FETCH_ASSOC); ?>
该逻辑完全符合你的需求:第一页满10条后,新提交的内容会自动排在第一页顶部,原来第一页最早的第10条记录会自动移动到第二页顶部。
4. 前端展示与分页导航
<!-- 上传表单 --> <form method="post" enctype="multipart/form-data" action="submit.php"> <div> <label>上传文本文件:</label> <input type="file" name="text_file" accept=".txt" required> </div> <div> <label>简短留言:</label> <input type="text" name="message" maxlength="200" required> </div> <button type="submit">提交</button> </form> <!-- 提交记录列表 --> <h3>公开提交记录</h3> <?php if (!empty($record_list)): ?> <ul> <?php foreach ($record_list as $item): ?> <li> <p>留言内容:<?php echo htmlspecialchars($item['message']); ?></p> <p>提交时间:<?php echo $item['created_at']; ?></p> <p><a href="<?php echo htmlspecialchars($item['file_path']); ?>" target="_blank">查看上传文件</a></p> </li> <?php endforeach; ?> </ul> <?php else: ?> <p>暂无提交记录</p> <?php endif; ?> <!-- 分页导航栏 --> <div class="pagination"> <!-- 上一页按钮 --> <?php if ($current_page > 1): ?> <a href="?page=<?php echo $current_page - 1; ?>">上一页</a> <?php endif; ?> <!-- 连续页码展示,默认展示当前页前后共5个页码,可自行调整 --> <?php $start_page = max(1, $current_page - 2); $end_page = min($total_pages, $current_page + 2); for ($i = $start_page; $i <= $end_page; $i++): ?> <?php if ($i == $current_page): ?> <span style="font-weight:bold;margin:0 4px;"><?php echo $i; ?></span> <?php else: ?> <a href="?page=<?php echo $i; ?>" style="margin:0 4px;"><?php echo $i; ?></a> <?php endif; ?> <?php endfor; ?> <!-- 下一页按钮 --> <?php if ($current_page < $total_pages): ?> <a href="?page=<?php echo $current_page + 1; ?>">下一页</a> <?php endif; ?> </div>
生产环境注意事项
- 所有数据库操作统一使用预处理语句,避免SQL注入风险
- 输出用户提交内容统一用
htmlspecialchars转义,避免XSS攻击 - 上传文件不要存放在web可执行目录下,避免恶意脚本执行
- 可给
created_at字段增加索引,提升大数据量下的分页查询性能
内容的提问来源于stack exchange,提问作者StevenNBick
相关产品推荐
相关产品推荐

