You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

启用Redis对象缓存后get_terms的hide_empty参数失效问题

问题原因

核心触发点是Redis对象缓存的get_terms查询缓存键生成逻辑存在缺陷,和WordPress默认参数补全逻辑不兼容:

  • 你的代码中没有显式传入hide_empty参数,WordPress执行查询时会自动补全该参数的默认值true,但绝大多数Redis对象缓存插件生成terms查询缓存键时,仅识别代码中手动传入的参数,不会将WordPress自动补全的默认参数纳入缓存键计算维度。
  • 站点内任意位置(包括后台渲染、其他插件/主题的自定义查询)只要曾经以hide_empty=false的配置查询过相同父ID、相同分类法(product_cat)的分类列表,Redis就会把包含空分类的结果集写入缓存。后续你当前的查询因为没有显式传hide_empty,生成的缓存键和前述查询完全一致,会直接读取到包含空分类的错误缓存结果,常规刷新缓存的操作无法避免这个缓存键冲突问题,刷新后依然可能被其他请求提前写入错误缓存。
  • 少数旧版本场景下,WooCommerce产品上下架、删除时没有同步更新Redis中存储的term计数缓存,会导致hide_empty判断时读取到错误的分类关联产品数,把实际无关联产品的空分类判定为非空分类返回。
修复方案

按优先级依次尝试即可:

  • 最稳妥的方案是不要依赖函数默认参数,在查询时显式声明所有核心参数,修改$args数组明确传入hide_empty => true,让缓存插件能正确识别参数差异,生成独立的缓存键,避免和其他查询的缓存串用,修改后的代码如下:
$parentid = 182;
$args = array(
    'parent'     => $parentid,
    'hide_empty' => true, // 显式声明参数,规避缓存键冲突
);
$terms = get_terms( 'product_cat', $args );

if ( $terms ) {
echo '<ul>';
foreach ( $terms as $term ) {
    echo '<li>';
        echo '<a href="' . esc_url( get_term_link( $term ) ) . '" class="' . $term->slug . '">';
        echo $term->name;
        echo '</a>';
    echo '</li>';
}
echo '</ul>';
}
  • 如果显式传参后问题依然存在,先升级Redis对象缓存插件到最新版本,修复已知的缓存键生成bug;也可以将terms缓存组配置为不持久化存储,避免跨请求的缓存污染。
  • 兜底兼容方案:获取到terms列表后手动过滤空分类,不依赖hide_empty的内置判断:
// 获取terms后增加过滤逻辑
foreach ( $terms as $index => $term ) {
    if ( (int) $term->count <= 0 ) {
        unset( $terms[$index] );
    }
}

内容的提问来源于stack exchange,提问作者Blue Li

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 10:06:29