0

这是我目前的做法:

$db->query(sprintf('INSERT INTO pages (title, content) VALUES ("%s", "%s")',
    $db->e​​sc($title),
    $db->e​​sc($content)));

如您所见,我通过将每个字符串传递给我的 $db->e​​sc() 方法来手动转义上述查询中的每个字符串。

首先让我表明我不想使用准备好的语句。

我能想到的最好办法是让我的 $db->query() 方法包装 sprintf() 并在每个字符串转换规范上自动调用 $db->e​​sc() - 如下所示:

$db->query('INSERT INTO pages (title, content) VALUES ("%s", "%s")',
    $标题,
    $内容);

这对我来说看起来很棒,但现在我的问题变成了如何正确解析格式字符串中的所有字符串转换规范并在每个相应的参数上调用 $db->e​​sc()(在将所有参数传递给 sprintf() 之前)?

你会用不同的方式来做吗?

4

2 回答 2

2

你应该阅读准备好的声明

准备:报表模板由应用程序创建并发送到数据库管理系统 (DBMS)。某些值未指定,称为参数、占位符或绑定变量(下面标记为“?”):

    `INSERT INTO PRODUCT (name, price) VALUES (?, ?)`

DBMS 对语句模板进行解析、编译和查询优化,并存储结果而不执行它。执行:稍后,应用程序为参数提供(或绑定)值,DBMS 执行语句(可能返回结果)。

它在 PHP 中的实现:PDOMySQLiPostgreSQL等。因此,没有理由自己实现它。就用它吧。

于 2013-05-08T05:10:31.690 回答
1

首先让我表明您使用准备好的语句。
您所说的非常自动的“转义”(尽管它必须称为格式化),正是准备好的语句的用途。
准备好的语句不一定必须基于数据库支持的本机准备好的语句。准备好的语句的一般思想是用占位符表示一些查询部分,并在用实际数据替换占位符时应用一些格式。所以 - 您的方法已经在使用占位符 AKA 准备好的语句。

但是你错过了一些重要的事情

  • 任何“逃避”都无济于事。必须改为应用正确的格式
  • 正确的字符串格式需要引用转义,因此您准备好的语句处理程序应该同时应用这两者。
  • 不止一种不同的 SQL 文字,每种都需要不同的格式。所以,要满足现实生活的需求,不能依赖单一的esc()功能

所以,你去 -你要求的这种包装器的代码,它可以正确格式化,因此你的查询不会比使用 PDO 更安全。尽管具有 PDO 的所有限制。

因此,如果您想正确格式化可能添加到查询中的所有内容,您将需要另一个包装器,一个更复杂的包装器: safeMysql

于 2013-05-08T05:35:08.487 回答