如何在未过滤的$wpdb->Get_Results函数中执行不同的SQL查询

时间:2021-01-15 作者:blueway

我看到了$wpdb->get_results 该函数未被核心代码清理($wpdb is get_results escaped).

例如,在以下代码中

$wpdb->get_results( "DELETE FROM `wp_postmeta` WHERE `meta_key` = \'likeiwould\' AND `meta_value` = \'{$array[\'item\']}\'" );
它应该执行mysql睡眠命令,但不起作用。

$array[\'item\'] = "123\';SELECT+sleep(10)\'"
结果:

DELETE FROM `wp_postmeta` WHERE `meta_key` = \'likeiwould\' AND `meta_value` = \'123\';SELECT+sleep(10)\'\'
所以,如果$wpdb->get_results 没有被核心代码清理,为什么我们不能在其中执行不同的sql查询?谢谢

1 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

如果$wpdb->get_results 没有被核心代码清理,为什么我们不能在其中执行不同的SQL查询?

因为wpdb class 使用(参见wpdb::_do_query() ) mysqli_query() (默认情况下)或mysql_query(), 不幸的是,这些功能do not support multiple queries 例如SELECT <query>; INSERT <query>; SELECT <query>.

因此,如果要使用wpdb, 您需要单独执行每个查询,如下所示:

// You cannot do this:
// And I mean, regardless the query is escaped/safe or not, this won\'t work.
$results = $wpdb->get_results( "SELECT <query>; INSERT <query>; SELECT <query>" ); // doesn\'t work

// But you can do this:
$results = $wpdb->get_results( "SELECT <query>" );
$rows = $wpdb->query( "INSERT <query>" ); // this works, but you should use $wpdb->insert(), though
$results = $wpdb->get_results( "SELECT <query>" );
针对您的评论:

get_results 在分号后提供多个SQL查询时,函数不起作用; 并在引号后添加反斜杠\', "

“关于这一点”;分号;"E;(例如,如DELETE <query>; SELECT <query>), 是的,你是对的。

关于这一点;添加反斜杠“;,是的,你也是对的,但更好/首选的方法是wpdb::prepare() 为安全执行准备SQL查询。

// We used the same query, but different data.

// Query 1: Not escaped, but data is good, so no errors thrown.
$value = \'"Foo"\'; // intentionally not escaped
$results = $wpdb->get_results( "SELECT ID, post_title FROM $wpdb->posts WHERE post_title = \'{$value}\' LIMIT 2" );
// Generated SQL: SELECT ID, post_title FROM wp_posts WHERE post_title = \'"Foo"\' LIMIT 2

// Query 2: Not escaped, data is bad, thus results in a syntax error!
$value = "\'Foo\'"; // intentionally not escaped
$results = $wpdb->get_results( "SELECT ID, post_title FROM $wpdb->posts WHERE post_title = \'{$value}\' LIMIT 2" );
// Generated SQL: SELECT ID, post_title FROM wp_posts WHERE post_title = \'\'Foo\'\' LIMIT 2

// Query 3: Works good - data escaped manually, and no errors thrown.
$value = \'\\\'Foo\\\'\'; // backslashes added manually
$results = $wpdb->get_results( "SELECT ID, post_title FROM $wpdb->posts WHERE post_title = \'{$value}\' LIMIT 2" );
// Generated SQL: SELECT ID, post_title FROM wp_posts WHERE post_title = \'\\\'Foo\\\'\' LIMIT 2

// Query 4: Works good - data not escaped, but wpdb::prepare() is used, so no errors thrown.
$value = "\'Foo\'"; // intentionally not escaped
// But then, this query uses wpdb::prepare().
$results = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_title FROM $wpdb->posts WHERE post_title = %s LIMIT 2", $value ) );
// Generated SQL: SELECT ID, post_title FROM wp_posts WHERE post_title = \'\\\'Foo\\\'\' LIMIT 2

注释wpdb 使用mysql_query() 如果MySQLi函数不可用,或者如果名为WP_USE_EXT_MYSQL 已定义。

MySQLi支持multiple statements 使用mysqli_multi_query(), 但是(在写作时),wpdb 不使用该功能。