以下是我目前的工作方式:
$db->query(sprintf('INSERT INTO pages (title, content) VALUES ("%s", "%s")', $db->esc($title), $db->esc($content)));
正如您所看到的,我通过将每个字符串传递给我的$ db-> esc()方法手动转义上述查询中的每个字符串。
首先让我指出我不想使用准备好的陈述。
我能想到的最好的想法是让我的$ db-> query()方法包装sprintf()并在每个字符串转换规范上自动调用$ db-> esc() - 像这样:
$db->query('INSERT INTO pages (title, content) VALUES ("%s", "%s")', $title, $content);
这看起来很棒,但现在我的问题是如何正确解析格式字符串中的所有字符串转换规范,并在每个相应的参数上调用$ db-> esc()(在将所有内容传递给sprintf之前) ())?
你会采用不同的方式吗?
答案 0 :(得分:2)
您应该阅读prepared statement。
准备:语句模板由应用程序创建并发送到数据库管理系统(DBMS)。某些值未指定,称为参数,占位符或绑定变量(下面标记为“?”):
`INSERT INTO PRODUCT (name, price) VALUES (?, ?)`
DBMS在语句模板上解析,编译和执行查询优化,并存储结果而不执行它。 执行:稍后,应用程序提供(或绑定)参数的值,DBMS执行该语句(可能返回结果)。
它在PHP中的实施:PDO,MySQLi,PostgreSQL等。所以,没有理由自己实现它。只需使用它。
答案 1 :(得分:1)
首先让我指出你想要使用准备好的陈述
您正在谈论的非常自动的“转义”(尽管它必须被称为格式化)是准备好的语句。
Prepared语句不一定必须基于数据库支持的本机预准备语句。准备语句的一般思想是用占位符表示一些查询部分,并在用占位数替换占位符时应用一些格式。所以 - 你的方法已经在使用占位符AKA准备好的陈述。
但是你错过了一些重要的事情
esc()
函数所以,在这里 - the code for such a wrapper you're asking for,它可以更正格式化,因此您的查询的安全性不会低于PDO。尽管PDO具有所有限制。
因此,如果您想正确格式化所有内容,可能会将其添加到查询中,您将需要另一个包装器,一个更复杂的包装器:safeMysql