如何用PHP PDO与OOP实现用户图书删除功能?
咱们一步步来排查并解决这个删除按钮没反应的问题,你的代码里有几个关键问题得修正:
1. 缺失表单包裹,提交按钮无法触发请求
你现在的删除按钮是个submit类型的<input>,但它没被包裹在<form>标签里——浏览器根本不知道要把这个提交请求发去哪里!而且你把method='post'写在input上了,这个属性是属于<form>标签的,放在input上完全无效。
另外,你的查询语句只获取了书名,没拿到user_id和book_id,删除操作必须依赖这两个ID才能定位到要删除的关联记录。
修正方案:
首先修改getBooks里的SQL查询,把需要的ID字段查出来:
$query = "SELECT loginUser.id AS user_id, Library.id AS book_id, Library.nameOfBook FROM loginUser JOIN userBook ON userBook.user_id = loginUser.id JOIN Library ON userBook.book_id = Library.id WHERE loginUser.username=:username LIMIT $sql_start, $sql_limit";
然后在循环生成表格行时,给每个删除按钮套上<form>,并通过隐藏域传递user_id和book_id:
foreach($result as $row){ echo "<tr>"; // 用htmlspecialchars防止XSS攻击,安全细节不能少 echo "<td>" . htmlspecialchars($row['nameOfBook']) . "</td>"; echo "<td>"; // 包裹form,指定提交方式为POST,action留空表示提交到当前页面 echo "<form method='post' action=''>"; echo "<input type='hidden' name='user_id' value='".htmlspecialchars($row['user_id'])."'>"; echo "<input type='hidden' name='book_id' value='".htmlspecialchars($row['book_id'])."'>"; echo "<input type='submit' name='delete' value='Delete'>"; echo "</form>"; echo "</td>"; echo "</tr>"; }
2. 删除函数的SQL语法与参数逻辑错误
你的deleteBooks函数存在几个严重问题:
- 函数接收的
$id1、$id2参数直接被$_GET覆盖,而我们用的是POST提交,应该从$_POST取参数 - SQL语句里的
id1、id2没有用占位符,直接写会被当成字符串常量,不仅语法错误,还存在SQL注入风险 execute的参数写法不匹配占位符,逻辑混乱- 判断删除结果时用了字符串
"1",但rowCount()返回的是整数,应该用$result == 1
修正后的deleteBooks函数:
public function deleteBooks() { // 先检查必要的POST参数是否存在,避免报错 if(!isset($_POST['user_id'], $_POST['book_id'])){ return false; } $user_id = $_POST['user_id']; $book_id = $_POST['book_id']; // 使用命名占位符,彻底杜绝SQL注入 $query = "DELETE FROM userBook WHERE user_id = :user_id AND book_id = :book_id"; $statement = $this->db->prepare($query); // 绑定参数并执行 $statement->execute([ ':user_id' => $user_id, ':book_id' => $book_id ]); $result = $statement->rowCount(); // 返回是否成功删除(受影响行数为1表示删除成功) return $result == 1; }
3. 删除逻辑的触发时机错误
你现在把删除请求的判断放在了表格生成之后,而且调用deleteBooks时没有传参数。正确的逻辑应该是先处理删除请求,再展示最新的图书列表。
修正触发时机:
把删除请求的检查放在getBooks函数的最开头:
public function getBooks($start = 0, $limit = 2) { // 先处理删除请求,再查数据 if(isset($_POST['delete'])){ $this->deleteBooks(); } // 以下是原有的SQL查询和表格生成代码(已经做过前面的修正) $sql_start = $start * $limit; $sql_limit = $limit; $query = "SELECT loginUser.id AS user_id, Library.id AS book_id, Library.nameOfBook FROM loginUser JOIN userBook ON userBook.user_id = loginUser.id JOIN Library ON userBook.book_id = Library.id WHERE loginUser.username=:username LIMIT $sql_start, $sql_limit"; $statement = $this->db->prepare($query); $statement->execute([ ':username' => $this->username ]); $result = $statement->fetchAll(); // 生成表格(带form的删除按钮) echo "<table border='1'> <tr> <th>Books</th> <th>Action</th> </tr>"; foreach($result as $row){ echo "<tr>"; echo "<td>" . htmlspecialchars($row['nameOfBook']) . "</td>"; echo "<td>"; echo "<form method='post' action=''>"; echo "<input type='hidden' name='user_id' value='".htmlspecialchars($row['user_id'])."'>"; echo "<input type='hidden' name='book_id' value='".htmlspecialchars($row['book_id'])."'>"; echo "<input type='submit' name='delete' value='Delete'>"; echo "</form>"; echo "</td>"; echo "</tr>"; } echo "</table>"; }
总结关键修正点
- 给删除按钮添加
<form>包裹,通过隐藏域传递必要的user_id和book_id - 修改SQL查询,获取删除操作需要的ID字段
- 修复
deleteBooks函数的SQL占位符和参数逻辑,避免注入风险 - 调整删除逻辑的执行时机,先处理删除再展示最新列表
这样修改后,点击删除按钮应该就能正常触发删除操作,页面刷新后会展示更新后的图书列表了。
内容的提问来源于stack exchange,提问作者Second View
相关产品推荐
相关产品推荐

