mysqli、预处理语句和INSERT-SELECT语句

4

假设我有一个 InnoDB 数据库中的两个表:categoriesjokes;我使用 PHP/MySQLi 来完成这项工作。这两个表的结构如下:

CATEGORIES
id (int, primary, auto_inc)  |  category_name (varchar[64])
============================================================
1                               knock, knock

JOKES
id (int, primary, auto_inc)  |  category_id (int)  | joke_text (varchar[255])
=============================================================================
empty

感谢此处的先前的回答,我发现可以执行以下操作来添加由:$joke_text$category_id组成的新笑话。

INSERT INTO jokes (category_id, joke_text)
SELECT c.id, '$joke_text'
FROM categories AS c WHERE c.id = $category_id;

这样可以确保$category_id值引用了已存在的类别,而不需要使用外键(请忽略外键的问题,因为我的问题是为了帮助我学习“复杂”的预处理语句)。
所以这个方法很好用。然而,我现在正在尝试学习预处理语句,经过一整天的努力,我终于基本掌握了它。不幸的是,我完全不知道如何在mysqli下使用预处理语句执行上面的SQL查询,也没有找到关于这个问题的任何信息。
如果有人能帮我解决这个问题,我会非常感激。
2个回答

3

首先,您需要创建一条与您平常创建的语句非常相似的语句。

$stmt = $mysqli->prepare("INSERT INTO jokes (category_id, joke_text)
SELECT c.id, ?
FROM categories AS c WHERE c.id = ?;");

获取绑定到参数's'的语句,其中's'代表字符串数据,'i'代表整数。

$stmt->bind_param('si', $joke_text,$category_id);   // bind to the parameters

/* 执行预处理语句 */

$stmt->execute();

使用mysqli real_escape_string函数转义POST数据不是违背使用预处理语句的初衷吗?你使用预处理语句来跳过这一步骤。否则,就像调用addslashes函数然后再用real_escape_string函数转义一样。至少在我使用MySQLi之前转向PDO时,我读到了这个问题。请参见https://dev59.com/zW025IYBdhLWcg3wEhnr - Touch
我同意,这只是一种习惯 :) 可以安全地去除。 - skv
双重转义可能会导致发送一个单引号时出现两个单引号。这就是我看到安全问题的地方。最好我们建议去掉这个习惯。 :) - Touch
嗯,也许这看起来比实际情况要复杂得多。但是,我是否也想在 WHERE c.id = $category_id 语句中加上一个 ? 呢?这样它就会变成:WHERE c.id = ?,然后我只需要将 $category_id 添加为 stmt->bind_param 的第二个参数即可。 - EleventyOne
抱歉,编辑过了,忘记标注来源是数据库。 - skv
显示剩余3条评论

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接