我正在尝试使用php的PDO对象从mySQL表中删除匹配一对条件的所有行。我无法弄清楚它为什么不起作用:
//This deletes all comments for a given post;
//Querying database for existent comments on that post;
$this->query = $this->db->query(
"SELECT cid
FROM comments
WHERE id = '$html_data->id' AND pid = '$html_data->pid'"
);
//Fetching results into an array;
$this->rows = $this->query->fetchAll(PDO::FETCH_ASSOC);
//Deleting each comment on that post;
foreach ($this->rows as $this->row) {
$this->db->exec(
"DELETE from comments
WHERE cid = '$this->row['cid']'"
);
};
//Deleting the post itself;
$this->db->exec(
"DELETE from posts
WHERE id = '$html_data->id' AND pid = '$html_data->pid'"
);
//Deleting the post itself
有效,但foreach
循环中的部分不是出于某种原因。为了调试,我在循环中添加了以下内容:
echo "WHERE cid = '{$this->row['cid']}'";
它按预期返回:
WHERE cid = '1'
WHERE cid = '2'
因此,正在获取的数据不是问题。我也试过
WHERE id = '$html_data->id' AND pid = '$html_data->pid' AND cid = '$this->row['cid']'"
而不仅仅使用cid
而且它也不起作用。回应它,如预期的那样:
WHERE id = '1' AND pid = '1' AND cid = '1'
WHERE id = '1' AND pid = '1' AND cid = '2'
是的,我查看了我要删除的comments
表,id
,pid
和cid
与正在回复的表匹配。
答案 0 :(得分:2)
因此,解决此问题的更好方法是使用预准备语句并从查询中获取变量。这样,你既可以解决这个问题,也可以修复你现在拥有的安全问题(SQL注入)......
这是您的代码转换为高效的预准备语句:
$stmt= $this->db->prepare(
"SELECT cid
FROM comments
WHERE id = ? AND pid = ?"
);
$this->query = $stmt->execute(array($html_data->id, $html_data->pid));
$this->rows = $this->query->fetchAll(PDO::FETCH_ASSOC);
$deleteStmt = $this->db->prepare(
"DELETE from comments
WHERE cid = ?"
);
foreach ($this->rows as $row) {
$deleteStmt->execute(array($row['cid']));
};
//Deleting the post itself;
$stmt = $this->db->prepare(
"DELETE FROM posts
WHERE id = ? AND pid = ?"
);
$stmt->execute(array($html_data->id, $html_data->pid));
但是,您可以进一步清理它。处理此问题的最佳方法是使用外键。例如,让我们从评论表的pid
创建一个外键到帖子id
字段。
CREATE TABLE posts (
id INT,
name VARCHAR(35),
PRIMARY KEY (`id`)
) ENGINE = InnoDB;
CREATE TABLE comments (
id INT,
pid INT,
name VARCHAR(35),
PRIMARY KEY (`id`),
CONSTRAINT `posts_id`
FOREIGN KEY `posts_id` (`pid`)
REFERENCES `posts` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE = InnoDB
这里的美妙之处在于,你的大块代码就是这样:
$stmt = $this->db->prepare(
"DELETE FROM posts
WHERE id = ? AND pid = ?"
);
$stmt->execute(array($html_data->id, $html_data->pid));
当您删除注释时,约束(外键)将自动级联该删除以删除注释(因为如果没有,则会出现无效约束)...
答案 1 :(得分:0)
应该是
$this->db->exec(
"DELETE from comments
WHERE cid = '$this->row[cid]'"
);
或者您也可以使用
$this->db->exec(
"DELETE from comments
WHERE cid = '{$this->row['cid']}'"
);