WordPress使用meta_value_date按自定义日期元字段排序文章不生效问题
排查方向
- 打印实际执行的SQL语句确认排序规则是否生效:在
get_posts执行前临时添加以下代码,输出查询SQL后检查ORDER BY段是否优先使用_sm_tour_date对应字段排序,是否存在其他排序字段(如发布日期、菜单顺序)插入在自定义字段排序之前。
add_filter('posts_request', function($sql) { var_dump($sql); return $sql; }, 999);
- 校验元字段实际存储值:遍历查询返回的结果,逐个输出
get_post_meta($post->ID, '_sm_tour_date', true),确认是否存在隐藏字符、空格、旧数据格式不符合YYYY-MM-DD的情况。 - 确认是否存在未知查询钩子修改结果:在查询参数中显式添加
'suppress_filters' => true,屏蔽所有外部查询过滤器的影响后再测试排序结果。
解决建议
- 优先使用Meta Query子句别名排序:WordPress 4.2及以上版本支持直接用Meta Query子句别名作为排序依据,避免多个meta参数冲突导致的排序规则失效问题,修改后的代码如下:
$tourDates = get_posts(array( 'post_type' => 'tour', 'numberposts' => 4, 'suppress_filters' => true, 'meta_query' => array( 'tour_date_clause' => array( 'key' => '_sm_tour_date', 'compare' => '>=', 'value' => date('Y-m-d'), 'type' => 'DATE' ) ), 'orderby' => 'tour_date_clause', 'order' => 'ASC' ));
- 兜底手动排序:如果查询层的排序问题无法快速定位,可以拿到结果后用PHP手动排序保证结果正确,代码如下:
// 原有get_posts查询执行后添加以下代码 usort($tourDates, function($a, $b) { $dateA = strtotime(get_post_meta($a->ID, '_sm_tour_date', true)); $dateB = strtotime(get_post_meta($b->ID, '_sm_tour_date', true)); return $dateA - $dateB; });
内容的提问来源于stack exchange,提问作者Lee
相关产品推荐
相关产品推荐

