如何在PHP类的SQL查询中传入URL参数?
解决PHP类中SQL查询使用URL参数的问题(PDO实现)
原代码的核心问题有两个:静态SQL变量无法动态传入参数,直接拼接URL参数会引发SQL注入风险。改用PDO预处理语句可以彻底解决这些问题,以下是重构后的完整代码:
重构后的代码
常量配置类
class Constants{ // 数据库连接配置 const DB_SERVER = "localhost"; const DB_NAME = "digital_reader"; const USERNAME = "root"; const PASSWORD = "Wacoal?2023"; // 带参数占位符的SQL语句(:id为动态参数占位符) const SQL_SELECT_BY_ID = "SELECT * FROM science WHERE id = :id"; }
数据操作类(PDO实现)
class Scientists{ /** * 创建PDO数据库连接 * @return PDO|null 连接成功返回PDO对象,失败返回null */ public function connect(): ?PDO { try { $dsn = "mysql:host=" . Constants::DB_SERVER . ";dbname=" . Constants::DB_NAME . ";charset=utf8mb4"; $pdo = new PDO($dsn, Constants::USERNAME, Constants::PASSWORD); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); return $pdo; } catch(PDOException $e) { // 生产环境建议将错误写入日志,而非直接输出 error_log("数据库连接失败: " . $e->getMessage()); return null; } } /** * 根据ID查询科学数据 * @param int $id 从URL获取的合法ID参数 */ public function select(int $id): void { $pdo = $this->connect(); if($pdo === null) { echo json_encode([ "code" => 3, "message" => "数据库连接失败" ]); return; } try { // 准备预处理语句 $stmt = $pdo->prepare(Constants::SQL_SELECT_BY_ID); // 绑定参数并指定类型为整数,杜绝SQL注入 $stmt->bindParam(":id", $id, PDO::PARAM_INT); $stmt->execute(); // 获取关联数组格式的查询结果 $scientists = $stmt->fetchAll(PDO::FETCH_ASSOC); if(count($scientists) > 0) { echo json_encode([ "code" => 1, "message" => "查询成功", "result" => $scientists ]); } else { echo json_encode([ "code" => 0, "message" => "未找到对应数据" ]); } } catch(PDOException $e) { error_log("查询执行失败: " . $e->getMessage()); echo json_encode([ "code" => 2, "message" => "查询出错" ]); } finally { // 手动释放连接资源 $pdo = null; } } } // 外部调用:处理URL参数并执行查询 if(isset($_GET['id']) && is_numeric($_GET['id'])) { $id = (int)$_GET['id']; $scientists = new Scientists(); $scientists->select($id); } else { echo json_encode([ "code" => 4, "message" => "无效的ID参数,请传入合法数字" ]); }
关键改进说明
- 避免SQL注入:使用PDO预处理语句,通过参数绑定替代字符串拼接,确保参数被安全解析
- 参数合法性校验:先检查URL参数
id是否存在且为数字,再转为整数类型,过滤非法输入 - 错误处理优化:用try-catch捕获PDO异常,生产环境通过日志记录错误,避免泄露敏感信息
- 代码规范性:用
const存储常量值,添加返回类型声明,finally块确保数据库连接被正确释放
内容的提问来源于stack exchange,提问作者shasha gunasekara
相关产品推荐
相关产品推荐

