使用多占位符(args)的wpdb :: prepare()

时间:2018-04-05 03:46:17

标签: php mysql wordpress

我想查询所有用户角色"订阅者"或"管理员"

$ARRAY = array('%subscriber%','%administrator%');

$query = $wpdb->prepare( "
    SELECT *
    FROM {$wpdb->usermeta}
    WHERE meta_value IN %s
    ORDER BY user_id
    DESC LIMIT {$limit} OFFSET {$offset}
",  $ARRAY );

错误:注意:错误地调用了wpdb :: prepare。该查询仅预期一个占位符,但已发送多个占位符的数组。

我想使用多个占位符,如何修复?谢谢!

3 个答案:

答案 0 :(得分:1)

使用LIKE运算符和AND条件代替IN()函数。

您可以尝试:

$ARRAY = array('%subscriber%','%administrator%');

$query = $wpdb->prepare( "
    SELECT *
    FROM {$wpdb->usermeta}
    WHERE meta_value LIKE %s OR meta_value LIKE %s
    ORDER BY user_id
    DESC LIMIT {$limit} OFFSET {$offset}
",  $ARRAY );

答案 1 :(得分:0)

您需要使用 implode 函数将数组扩展为字符串,因为它需要传递字符串。

$ARRAY = array('%subscriber%','%administrator%');
$array_placeholders = implode( ', ', array_fill( 0, count( $ARRAY ), '%s' ) );

$query = $wpdb->prepare( "
    SELECT *
    FROM {$wpdb->usermeta}
    WHERE meta_value IN ( $array_placeholders )
    ORDER BY user_id
    DESC LIMIT {$limit} OFFSET {$offset}
",  $ARRAY );

答案 2 :(得分:0)

首先,我应该指出您的查询存在安全问题。您正在寻找带有“订户”和“管理员”字样的任何元值。因此,使用您网站上的任何用户帐户,我都可以将我的名字或bio设置为包含“管理员”,您的查询就会将我作为一个。如果您正在寻找角色,请确保您对角色明确:

$prefix = $wpdb->get_blog_prefix();
... "WHERE meta_key = '{$prefix}_capabilities' AND " ...

第二个虽然不正确,但安德鲁的答案看起来更好,因为您没有像在卡洛的答案中那样硬编码要在查询本身中查找的角色数量。假设您必须查询15个角色。但是不正确的原因是,因为功能元数据值是一个序列化的PHP数组,所以不幸的是,您不能在那里真正使用IN(),但是使用相同的想法,您可以执行以下操作:

$prefix = $wpdb->get_blog_prefix();
$roles = array( 'subscriber', 'administrator' );
$parts = array();

foreach ( $roles as $role ) {
    $parts []= $wpdb->prepare( "meta_value LIKE %s",
        '%' . $wpdb->esc_like( $role ) . '%' );
}

$parts_sql = implode( " OR ", $parts );
$sql = "SELECT * FROM {$wpdb->usermeta}
    WHERE meta_key = '{$prefix}capabilities'
    AND ({$parts_sql})";

$wpdb->get_results( $sql, ARRAY_A );

最后,即使您确实以这种方式获得站点管理员,也请确保您不允许他们仅根据其角色执行任何操作,并在适用于current_user_can()user_can()的情况下运行功能检查。

希望有帮助。