更新MySQL数据时触发PDO SQL语法错误,请求排查解决
错误信息
Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 in C:\MAMP\htdocs\PHP\mattina\14_07_user_squadra\edit.php:41 Stack trace: #0 C:\MAMP\htdocs\PHP\mattina\14_07_user_squadra\edit.php(41): PDOStatement->execute() #1 {main} thrown in C:\MAMP\htdocs\PHP\mattina\14_07_user_squadra\edit.php on line 41
问题分析与修复方案
1. SQL语法错误:多余的右括号
你的UPDATE语句末尾多了一个不必要的右括号,直接导致SQL语法解析失败:
// 错误写法:末尾多了一个 ) $statement = $pdo->prepare("UPDATE users SET name = :name , surname = :surname , adress = :adress , city = :city, type_id = :type_id WHERE id = $id)");
去掉多余的括号即可:
$statement = $pdo->prepare("UPDATE users SET name = :name , surname = :surname , adress = :adress , city = :city, type_id = :type_id WHERE id = :id");
2. $id变量作用域缺失
POST请求时,$id是空字符串——你只在GET请求时从$_GET['id']赋值了$id,但POST请求没有获取id的逻辑,导致WHERE子句变成WHERE id = '',触发语法错误。
解决方法:
- 在编辑表单中添加隐藏字段传递id:
<input type="hidden" name="id" value="<?php echo $users[0]['id']; ?>">
- 在POST逻辑中获取并转义id:
if ($_SERVER["REQUEST_METHOD"] == "POST") { $id = (int)$_POST['id']; // 新增这行,强制转为整数避免注入 $name = htmlspecialchars($_POST['name']); // ... 其他变量赋值 }
3. 修复SQL注入风险
你直接将$id拼入SQL语句,存在严重的SQL注入风险,必须改为参数绑定:
// 使用:id参数代替直接拼接$id $statement = $pdo->prepare("UPDATE users SET name = :name , surname = :surname , adress = :adress , city = :city, type_id = :type_id WHERE id = :id"); // 绑定id参数,指定类型为整数进一步加固 $statement->bindValue(':id', $id, PDO::PARAM_INT); // ... 其他参数绑定
修正后的完整代码片段
$title = 'edit user'; $pdo = new PDO('mysql:host=localhost;port=3306;dbname=test_one_to_many', 'root', 'root'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $error = false; $id = ""; if ($_SERVER["REQUEST_METHOD"] == "GET") { $id = (int)$_GET['id']; // SELECT语句也改为参数绑定,彻底避免注入 $statement = $pdo->prepare("SELECT * FROM users WHERE id = :id"); $statement->bindValue(':id', $id, PDO::PARAM_INT); $statement->execute(); $users = $statement->fetchAll(PDO::FETCH_ASSOC); $query = $pdo->query("SELECT * FROM type"); $privileges = $query->fetchAll(); } if ($_SERVER["REQUEST_METHOD"] == "POST") { $id = (int)$_POST['id']; $name = htmlspecialchars($_POST['name']); $surname = htmlspecialchars($_POST['surname']); $adress = htmlspecialchars($_POST['adress']); $city = htmlspecialchars($_POST['city']); $type_id = (int) htmlspecialchars($_POST['type_id']); // 修正SQL语句,使用参数绑定id $statement = $pdo->prepare("UPDATE users SET name = :name , surname = :surname , adress = :adress , city = :city, type_id = :type_id WHERE id = :id"); $statement->bindValue(':name', $name); $statement->bindValue(':surname', $surname); $statement->bindValue(':adress', $adress); $statement->bindValue(':city', $city); $statement->bindValue(':type_id', $type_id); $statement->bindValue(':id', $id, PDO::PARAM_INT); $statement->execute(); header("location:index.php"); exit; // 跳转后必须exit,防止后续代码执行 }
内容的提问来源于stack exchange,提问作者Bubu23

