这开始于我试图弄清楚如何让一些东西发挥作用,却被我得到的结果所困惑。当我测试以确保我把这个问题写清楚时,我偶然发现了答案。现在这个问题变成了为什么它会这样,因为它让我非常困惑,让我相信这个问题与它是完全不同的。
我需要在我创建的wordpress数据库中查询一个自定义表。我需要几列,可能有多行,所以我使用
$wpdb->get_results
. 但是,我知道防止sql注入非常重要,因此强烈建议将其与
$wpdb->prepare
. 在我看到的所有示例中,有几种方法似乎对其他人有效,例如:
$wpdb->get_results($wpdb->prepare(
"SELECT * FROM %s WHERE ADDRESS LIKE %%%s%%", $tableName, $address
));
或
$wpdb->get_results($wpdb->prepare(
"SELECT * FROM %s WHERE ADDRESS LIKE %s", $tableName, '%' . $address . '%'
));
然而,在开发此程序时,我使用了一个变量并打印到屏幕以进行调试,例如:
$theQuery = $wpdb->prepare(
"SELECT * FROM %s WHERE ADDRESS LIKE %s", $tableName, '%' . $address . '%'
);
printf(nl2br("theQuery: " . $theQuery . PHP_EOL));
查看结果时,我收到以下信息:
theQuery: SELECT * FROM 'wp_table' WHERE ADDRESS LIKE '{38f7caa660e456637b3924006588169e1912b28c0a81d0a4ae0d77885704a425}11th ST{38f7caa660e456637b3924006588169e1912b28c0a81d0a4ae0d77885704a425}'
看起来
$wpdb->准备
语句导致%转换为某种类型的GUID。每次刷新页面时,guid的值都会发生变化,因此每次都会为%符号生成新的guid。这显然是它提供针对sql注入的安全性的一部分,但由于我不知道它会以这种方式运行,也从未在文档中看到过,所以我认为这是我的问题。我尝试了很多组合,但它总是无法检索到任何结果,我一直认为这是因为它与那些guid的行为不正确。我最终发现,实际的问题是将表名作为参数包含在prepare语句中。这会导致查询在表名周围使用单引号,导致MySQL语法错误,并且不会返回任何结果。
为什么它会生成这些guid?在测试过程中,有没有办法将它们作为%打印到浏览器中进行调试?
非常感谢。