从 mysql_query 转换为准备好的语句 (mysqli/PDO)?必要的?

Posted

技术标签:

【中文标题】从 mysql_query 转换为准备好的语句 (mysqli/PDO)?必要的?【英文标题】:Converting from mysql_query's to prepared statements (mysqli/PDO)? Necessary? 【发布时间】:2012-08-23 13:54:52 【问题描述】:

过去几周我一直在学习 phpmysql,我现在才听说准备好的语句和 PDO/mysqli。我做了一些阅读,人们说这样的话:

$getFromDatabase = mysql_query("SELECT * FROM table WHERE userid='$id'");
while($row = mysql_fetch_assoc($getFromDatabase))
    stuff();

...不会再工作了。我在我的代码中经常使用类似的东西。我也在阅读很多关于准备好的语句如何更好地防止注入的内容。我已经彻底了解了它是如何变得更好的,但是它是否值得从 mysql_real_escape_string() 切换出来?是否需要切换到Mysqli或PDO?在什么情况下,mysql_real_escape_string() 可以在准备好的语句无法绕过的情况下被绕过?

【问题讨论】:

它现在可以工作...mysql_*() 函数正面临未来弃用。建议开始远离它们。 而准备好的语句优于mysql_real_escape_string()的主要原因是。您可以并且在某些时候会忘记调用它。我们都这样做了。 P.S. $id 周围不应有单引号。这是一个数字,而不是字符串文字。你不引用数字。 @DanGrossman 如果 ID 是 GUID 怎么办? Are PDO prepared statements sufficient to prevent SQL injection? 的可能重复项 【参考方案1】:

这是必要的,因为mysql_query 在软件方面是一个古老的人工制品。它是 MySQL 数据库接口的Model T,如果不按您应该的方式完全 使用,它会显得笨重、不可靠并且非常危险。如果您不是非常小心,您会犯错误,如果有人在您的网站上使用automatic SQL injection bug detection tool,即使是很小的错误也不会被忽视。

基本上你是在借用mysql_query的时间。

如果您使用mysqli 或 PDO 并且勤于使用占位符,则 SQL 注入错误的风险非常低。可能需要半个小时左右才能弄清楚如何将旧代码转换为这些新方法,确实没有陡峭的学习曲线,并且这些知识将为您将来节省很多麻烦。如果您使用mysqli 和基本占位符,转换现有代码通常不是什么大问题。我敢打赌,你在修补时甚至会发现一些严重的错误。

就好处而言,您无需拨打任何mysql_real_escape_string 电话,只需使用bind_param,您不必担心错过某个变量的转义。从长远来看,实际上工作量要少得多。

此外,使用?:id 之类的命名占位符使您的查询更易于阅读、调试和维护。此外,您可以重复使用相同的语句并将不同的值绑定到它,最终使您的应用程序更快。

使用mysql_query 编写安全代码是可能的,但你为什么要这样做?该接口被列为已弃用,这是将其从 PHP 中完全删除的初步阶段。如果您想要一个面向未来的应用程序,最好使用受支持的接口之一。

【讨论】:

以上是关于从 mysql_query 转换为准备好的语句 (mysqli/PDO)?必要的?的主要内容,如果未能解决你的问题,请参考以下文章

在 PHP 中到处使用准备好的语句? (PDO)

在 Java 中将动态 SQL 查询转换为准备好的语句

我啥时候应该使用准备好的语句?

如何将此代码转换为准备好的语句或 jdbc 中的语句? [关闭]

为准备好的语句创建插入查询

从准备好的语句中获取数据