WordPress:多个搜索词或加入多个WP_Queries

时间:2016-12-01 00:34:29

标签: php wordpress

我有以下代码:

$args = array(
    's'                 => 'Apple',
    'cat'               => 80,
    'posts_per_page'    => -1,
    'orderby'           => date,
    'order'             => desc,
);
$query = new WP_Query( $args );
echo $query->found_posts.'<br /><br />';
if ( $query->have_posts() ) {
    while ( $query->have_posts() ) { $query->the_post();
        echo the_time("Y.m.d"); echo ': '; echo the_title(); echo '<br />';
    }
}

它会搜索类别80以查找包含 Apple 一词的任何帖子,然后成功输出此类帖子的列表,例如

2

2016.10.10: Apple pie
2016.10.01: Apple juice

如果我还要显示包含 Banana 一词的所有帖子,那么我只需重复代码's' => 'Apple'替换为's' => 'Banana'并获取类似

1

2016.10.05: Banana fresh

非常简单,直到我想使用单个列表输出两个搜索结果,如

3

2016.10.10: Apple pie
2016.10.05: Banana fresh
2016.10.01: Apple juice

我需要你的帮助,因为我不知道如何实现这一目标。

到目前为止,我已经尝试了

$args = array(
    's'                 => array('Apple','Banana'),
    'cat'               => 80,
    'posts_per_page'    => -1,
    'orderby'           => date,
    'order'             => desc,
);

$args = array(
    array('s' => 'Apple',),
    array('s' => 'Banana',),
    'cat'               => 80,
    'posts_per_page'    => -1,
    'orderby'           => date,
    'order'             => desc,
);

即使子数组中只有一个元素,两者都返回给定类别的所有帖子,因此似乎's'无法放入子数组或包含数组作为参数。或者我在某个地方输错了但我无法抓到哪里。

2 个答案:

答案 0 :(得分:2)

虽然您的解决方案明确有效,但我想提交另一种利用WordPress提供的过滤器的可能解决方案。通过这种方式,我相信这个解决方案更符合“WordPress方式”:

// Hook into the WP_Query filter to modify the search query
add_filter( 'posts_search', 'make_search_any_terms', 10, 2 );

/**
 * Function to convert search to "any" terms instead of "all" terms.
 * WordPress automatically passes in the two arguments.
 * 
 * @param string $search
 * @param WP_Query $query
 *
 * @return string
 */
function make_search_any_terms( $search, $query ) {
    // If it's not a search, then do nothing
    if ( empty( $query->is_search ) ) {
        return $search;
    }

    global $wpdb;

    $search_terms = get_query_var( 'search_terms' );

    // This code adapted from WP_Query "parse_search" function
    $search    = '';
    $searchand = '';
    foreach ( $search_terms as $term ) {
        $like                        = '%' . $wpdb->esc_like( $term ) . '%';
        $q['search_orderby_title'][] = $wpdb->prepare( "$wpdb->posts.post_title LIKE %s", $like );

        $like = '%' . $wpdb->esc_like( $term ) . '%';
        $search .= $wpdb->prepare( "{$searchand}(($wpdb->posts.post_title LIKE %s) OR ($wpdb->posts.post_content LIKE %s))", $like, $like );
        // This is the significant change - originally is "AND", change to "OR"
        $searchand = ' OR ';
    }

    if ( ! empty( $search ) ) {
        $search = " AND ({$search}) ";
        if ( ! is_user_logged_in() ) {
            $search .= " AND ($wpdb->posts.post_password = '') ";
        }
    }

    return $search;
}

将其与SINGLE搜索查询一起使用:

$args = array(
    's'                 => 'Apple Banana Orange',
    // ...
);

$results = WP_Query( $args );

您将获得 香蕉橙色的所有结果。

通过这种方式,您可以拥有一个查询和一组结果,只需循环遍历它。

注意:以上代码通常放在主题的functions.php文件中。

答案 1 :(得分:1)

当我在等待准备好的答案时,我也在研究PHP手册和WP Codex,所以我最终得到了以下工作解决方案。

如果有人会为同一个问题搜索答案,那么就是:

<?php

// Searching for posts with "Apple" in their content within category with the id 80
$args_apple = array('s' => 'Apple', 'cat' => 80, 'posts_per_page' => -1);
$query_apple = new WP_Query( $args_apple );
wp_reset_query();

// Searching for posts with "Banana" in their content within category with the id 80
$args_banana = array('s' => 'Banana', 'cat' => 80, 'posts_per_page' => -1);
$query_banana = new WP_Query( $args_banana );
wp_reset_query();

// Searching for posts with "Orange" in their content within category with the id 80
$args_orange = array('s' => 'Orange', 'cat' => 80, 'posts_per_page' => -1);
$query_orange = new WP_Query( $args_orange );
wp_reset_query();

// Joining results, excluding duplicates with wrapping array_merge() into array_unique()
$result = new WP_Query();
$result->posts = array_unique(array_merge(
    $query_apple->posts,
    $query_banana->posts,
    $query_orange->posts
), SORT_REGULAR); // While PHP manual states this parameter is
                  // optional for array_unique(), in this case
                  // it is obligatory

// Showing the number of results
$result->post_count = count( $result->posts );
echo $result->post_count.'<br /><br />';

// Sorting results by date
usort($result->posts, 'order_by_date');
function order_by_date( $a, $b ) {
    $a_date = $a->post_date;
    $b_date = $b->post_date;
    return ( strcmp($a_date, $b_date ) > 0 ) ? -1 : 1; // Sort descending
//  return ( strcmp($a_date, $b_date ) > 0 ) ? 1 : -1; // Sort ascending
}

// The search results output loop
if ( $result->have_posts() ) {
    while ( $result->have_posts() ) { $result->the_post();
        // Start making your own output
        echo the_time("Y.m.d");
        echo ': ';
        echo the_title();
        echo '<br />';
        // Stop making your own output
    }
}
wp_reset_query();

?>

上面所有代码我唯一不喜欢的是对合并数组项进行排序的额外函数。但是我花了一半时间来找到一种方法来使用内部参数对合并数组进行排序,但没有成功。

结果就像

7

2016.10.21: Banana
2016.10.15: Sliced orange
2016.10.09: Banana fresh
2016.10.07: Apple juice
2016.10.05: Apple pie
2016.10.03: Orange
2016.10.01: Apple

合并数组的数量似乎不受限制,只是不要忘记为每个$args_name使用唯一的$query_nameWP_Query()

并始终使用wp_reset_query()关闭每个查询。