WordPress通过自定义分类法获取自定义文章仅init钩子生效,如何获取文章数组?
问题原因
你的判断是对的,WordPress 中自定义文章类型、自定义分类法的标准注册时机都是挂载在 init 钩子下执行,默认优先级为10。如果在 init 钩子触发前就调用 get_portfolio_posts(),此时分类法、自定义文章类型还未被注册到 WordPress 系统中,tax_query 会被判定为无效,自然返回空数组。
解决方案
根据你使用场景的不同,可选以下任意一种方案:
1. 模板文件中直接调用
如果你是在主题/子主题的模板文件(如 page.php、archive-portfolio.php 或自定义页面模板)中需要使用该文章数组,直接调用即可:
// 直接写在模板代码对应位置即可正常拿到返回值 $portfolio_posts = get_portfolio_posts();
模板文件的加载时机远晚于 init 钩子,此时所有自定义内容类型都已注册完成,不会返回空。
2. 全局作用域/非模板场景下缓存结果
如果你需要在 functions.php、插件文件的全局作用域中提前声明该变量,可以写一个带静态缓存的获取方法,确保查询在 init 钩子之后执行:
// 先保留你原有查询方法 function get_portfolio_posts() { $tax_query = [ 'relation' => 'AND', [ 'taxonomy' => 'project-type', 'field' => 'slug', 'terms' => 'mobile', ], [ 'taxonomy' => 'project-industry', 'field' => 'slug', 'terms' => 'health-fitness', ], ]; $posts = get_posts([ 'post_type' => 'portfolio', 'posts_per_page' => -1, 'tax_query' => $tax_query, ]); return $posts; } // 新增带缓存的获取方法 function get_cached_portfolio_posts() { static $posts_cache = null; if (null === $posts_cache) { // 已过init钩子时机,直接查询 if (did_action('init')) { $posts_cache = get_portfolio_posts(); } else { // 未到时机,挂载到init钩子后执行查询,优先级设为20(晚于默认的分类法/文章类型注册优先级10) add_action('init', function() use (&$posts_cache) { $posts_cache = get_portfolio_posts(); }, 20); } } return $posts_cache; }
后续所有需要用到文章数组的位置,统一调用 get_cached_portfolio_posts() 即可拿到非空结果:
// 全局声明变量 $portfolio_posts = get_cached_portfolio_posts(); // 任意init之后的执行场景下都可以直接使用该变量,比如其他钩子回调、模板文件中 add_action('wp_head', function() { global $portfolio_posts; // 这里就可以正常操作$portfolio_posts });
3. 挂载到晚于init的钩子中调用
如果你是在自定义逻辑中使用,只需要将调用逻辑挂载到 init 之后触发的钩子即可,常用的可选钩子有 wp_loaded、template_redirect 等:
add_action('wp_loaded', function() { $posts = get_portfolio_posts(); // 在这里写你的业务逻辑即可正常拿到返回值 });
内容的提问来源于stack exchange,提问作者forever_young
相关产品推荐
相关产品推荐

