WordPress问题:当get_posts无结果时WP_Query返回全部文章
WordPress查询异常修复:空post__in返回全部文章的解决办法
问题场景
我编写了一段WordPress代码,意图获取两种条件下的parvandeh类型文章ID,再通过WP_Query展示对应文章。代码如下:
<?php $user_id = get_current_user_id(); $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; $args_a = get_posts(array( 'fields' => 'ids', 'posts_per_page' => -1, 'post_type' => array('parvandeh'), 'author' => $user_id )); $args_b = get_posts(array( 'fields' => 'ids', 'posts_per_page' => -1, 'post_type' => array('parvandeh'), 'meta_query' => array( array( 'key' => 'parbandeh_masool', 'value' => $user_id, ), ), )); $post_ids = array_merge( $args_a, $args_b); $wp_query = new WP_Query(array( 'post_type' => 'parvandeh', 'post__in' => $post_ids, 'posts_per_page' => 15, 'paged' => $paged, 'orderby' => 'date', 'order' => 'DESC' )); ?>
当两个get_posts都未查询到任何ID时,WP_Query会返回所有parvandeh类型的文章,这不符合预期。
问题根源
WP_Query有个默认处理逻辑:如果post__in参数传入的是空数组,它会直接忽略这个条件,仅依据post_type等其他参数返回结果,因此出现了返回全部文章的情况。
修复方案
在初始化WP_Query之前,先判断合并后的$post_ids是否为空。如果为空,就给post__in赋值一个不存在的文章ID(比如array(0)),这样查询会返回空结果;如果不为空,就正常使用合并后的ID数组。
修改后的完整代码:
<?php $user_id = get_current_user_id(); $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; $args_a = get_posts(array( 'fields' => 'ids', 'posts_per_page' => -1, 'post_type' => array('parvandeh'), 'author' => $user_id )); $args_b = get_posts(array( 'fields' => 'ids', 'posts_per_page' => -1, 'post_type' => array('parvandeh'), 'meta_query' => array( array( 'key' => 'parbandeh_masool', 'value' => $user_id, ), ), )); $post_ids = array_merge( $args_a, $args_b); // 处理空ID数组,确保无匹配结果 if (empty($post_ids)) { $post_ids = array(0); } $wp_query = new WP_Query(array( 'post_type' => 'parvandeh', 'post__in' => $post_ids, 'posts_per_page' => 15, 'paged' => $paged, 'orderby' => 'date', 'order' => 'DESC' )); ?>
额外优化思路
可以将两次get_posts的查询合并为一次WP_Query,用SQL的OR逻辑同时匹配两个条件,减少数据库查询次数,代码更简洁。这里需要借助posts_where过滤器来实现主表字段(post_author)和meta字段的OR关系:
<?php $user_id = get_current_user_id(); $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; // 添加过滤器修改查询条件 add_filter('posts_where', function($where) use ($user_id) { global $wpdb; $where .= " OR ({$wpdb->postmeta}.meta_key = 'parbandeh_masool' AND {$wpdb->postmeta}.meta_value = {$user_id})"; return $where; }); $wp_query = new WP_Query(array( 'post_type' => 'parvandeh', 'posts_per_page' => 15, 'paged' => $paged, 'orderby' => 'date', 'order' => 'DESC', 'author' => $user_id, 'meta_query' => array( array( 'key' => 'parbandeh_masool', 'compare' => 'EXISTS' // 确保meta表被关联 ) ) )); // 移除过滤器避免影响后续查询 remove_filter('posts_where', '__return_false'); ?>
这个方案只需要一次数据库查询,效率更高,同时避免了空数组的问题。
内容的提问来源于stack exchange,提问作者Ahmad Karimi
相关产品推荐
相关产品推荐

