如何修改此$wpdb查询以接受POST状态数组

时间:2013-08-21 作者:Andrew

我正在使用来自this accepted 答案,它获取自定义字段键的所有值(十字柱)。

如何修改它以允许post状态数组?

function get_meta_values( $key = \'\', $type = \'post\', $status = \'publish\' ) {
    global $wpdb;

    if( empty( $key ) )
    return;

    $r = $wpdb->get_col( $wpdb->prepare( "
        SELECT pm.meta_value FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = \'%s\' 
        AND p.post_status = \'%s\' 
        AND p.post_type = \'%s\'
    ", $key, $status, $type ) );

    return $r;
}
像这样的东西(不起作用)

function get_meta_values( $key = \'\', $type = \'post\', $status = array( \'publish\', \'draft\' ) ) {
    global $wpdb;

    if( empty( $key ) )
    return;

    $r = $wpdb->get_col( $wpdb->prepare( "
        SELECT pm.meta_value FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = \'%s\' 
        AND p.post_status = \'%s\' 
        AND p.post_type = \'%s\'
    ", $key, $status, $type ) );

    return $r;
}

3 个回复
SO网友:keesiemeijer

使用IN operator 对于阵列。

使用时$wpdb->prepare() 不必在字符串占位符周围使用引号%s. 字符串占位符将自动引用。这也是使用时必须采取预防措施的原因$wpdb->prepare() 如果数组值是字符串,则使用IN运算符。

第一个示例不使用post stati的占位符,而是直接将它们(逗号分隔并引用)插入查询字符串中

function get_meta_values( $key = \'\', $type = \'post\', $status = array( \'publish\', \'draft\' ) ) {
    global $wpdb;

    if ( empty( $key ) ) {
        return;
    }

    // escape the status values
    $status = array_map( \'esc_sql\', (array) $status );

    // $status_string: a comma separated string with quoted post stati
    // $status_string = "\'publish\', \'draft\'";
    $status_string = "\'" . implode( "\', \'", $status ) . "\'";

    $query = "
        SELECT pm.meta_value FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = \'%s\'
        AND p.post_status IN ( $status_string )
        AND p.post_type = \'%s\'";

    $r = $wpdb->get_col( $wpdb->prepare( $query, $key, $type ) );

    return $r;
}
第二个示例使用此答案中的方法转换数组https://stackoverflow.com/a/10634225

function get_meta_values( $key = \'\', $type = \'post\', $status = array( \'publish\', \'draft\' ) ) {
    global $wpdb;

    if ( empty( $key ) ) {
        return;
    }

    // $status_string: a comma separated string with string placeholders (%s)
    // $status_string = "%s, %s";
    $status_string = implode( \', \', array_fill( 0, count( $status ), \'%s\' ) );

    //parameters array for call_user_func_array callback function $wpdb->prepare
    $prepare = array();

    // the query is the first parameter
    $prepare[] = "
        SELECT pm.meta_value FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = %s
        AND p.post_status IN ($status_string)
        AND p.post_type = %s
    ";

    // from here on out add to the $prepare array in the same order as inside the query
    $prepare[] = $key;

    foreach ( $status as $s ) {
        $prepare[] = $s;
    }

    $prepare[] = $type;

    // calling $wpdb->prepare() with the $prepare array
    $query = call_user_func_array( array( $wpdb, \'prepare\' ), $prepare );

    $r = $wpdb->get_col( $query );

    return $r;
}
注意:如果在生产中使用,这两个示例的编码都应该更加防御性(is\\u array()等)。

SO网友:Stephen Harris

只需内爆传递的数组:

function get_meta_values( $key = \'\', $type = \'post\', $status = array( \'publish\', \'draft\' ) ) {
    global $wpdb;

    if( empty( $key ) )
        return;

    //First escape the status, since we don\'t use it with $wpdb->prepare()    
    $status = esc_sql( $status );

    //If its an array, convert to string
    if( is_array( $status ) ){
        $status = implode( \', \', $status ); //e.g. "publish, draft"
    }

    $r = $wpdb->get_col( $wpdb->prepare( 
        "SELECT pm.meta_value FROM {$wpdb->postmeta} AS pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = %s
        AND p.post_status IN( {$status} ) 
        AND p.post_type = %s", 
        $key, $type ) );

    return $r;
}
这允许您通过$status 作为字符串或数组。

SO网友:Kumar

不要将状态作为数组,而应将其作为查询中的字符串,如

function get_meta_values( $key = \'\', $type = \'post\', $status = array( \'publish\', \'draft\' ) ) {
    global $wpdb;

    if ( empty( $key ) ) {
        return;
    }

    if( is_array( $status ) ){
        $status = implode( \', \', $status ); //e.g. "publish, draft"
    }
    $r      = $wpdb->get_col( $wpdb->prepare( "
    SELECT pm.meta_value FROM {$wpdb->postmeta} pm
    LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
    WHERE pm.meta_key = \'%s\'
    AND p.post_status IN ({$status})
    AND p.post_type = \'%s\'
    LIMIT 10", $key, $type ) );

    return $r;
}
这很有效,我已经测试过了。

结束

相关推荐

已查询$wpdb,但未显示结果

我试图在页面模板上显示自定义帖子类型的列表。当我查看页面时,我看到的不是不同的帖子,而是实际页面的重复。例如,如果我有5篇文章,实际页面(页眉内容页脚)将显示五次。看起来查询正在运行。。。在某种程度上,但我不确定是什么错了。以下是模板代码:<?php if ( have_posts() ) while ( have_posts() ) : the_post(); ?> <div id=\"post-<?php the_ID(); ?>\" <?