目前,这是不可能的。
什么时候\'pre_get_posts\'
跑,已经来不及停了WP_Query
执行查询。
WordPress本身,当您尝试查询不存在的分类时,会添加AND (0 = 1)
到WHERE
子句,以确保它不会很快返回任何结果。。。
有一个trac ticket 有一个补丁可能会在WP 4.6的核心中使用,它引入了一个新的过滤器:\'posts_pre_query\'
. 在该筛选器上返回数组将使WP_Query
停止处理并将提供的数组用作其posts数组。
这可以帮助你实现你想要做的事情。
等着瞧吧,你能做的任何事都是某种程度上的黑客行为,核心本身使用的技巧也是非常黑客的。
最近,当我想停止WordPress做一些我无法以干净的方式停止的事情时,我开始使用一个技巧:我抛出一个异常并捕获它以继续应用程序流。
我给你举个例子。注意,这里的所有代码都没有经过测试。
首先,让我们编写一个自定义异常:
class My_StopWpQueryException extends Exception {
private $query;
public static forQuery(WP_Query $query) {
$instance = new static();
$instance->query = $query;
return $instance;
}
public function wpQuery() {
return $this->query;
}
}
异常被设计为作为一种DTO来传输查询对象,以便在
catch
阻止您可以获取并使用它。
更好地解释代码:
function maybe_cached_query(WP_Query $query) {
$cached_query = wp_cache_get($query->query_vars_hash, \'globals\');
if ($cached_query instanceof WP_Query)
throw My_StopWpQueryException::forQuery($cached_query);
}
function cached_query_set(WP_Query $query) {
$GLOBALS[\'wp_query\'] = $query;
$GLOBALS[\'wp_the_query\'] = $query;
// maybe some more fine-tuning here...
}
add_action(\'pre_get_posts\', function(WP_Query $query) {
if ($query->is_main_query() && ! is_admin()) {
try {
maybe_cached_query($query);
} catch(My_StopWpQueryException $e) {
cached_query_set($e->wpQuery());
}
}
});
这或多或少应该是可行的,但是,例如,有很多钩子是你不会激发的
"the_posts"
还有更多。。。如果您有使用其中一个钩子触发的代码,它将中断。
您可以使用cached_query_set
函数启动主题/插件可能需要的一些挂钩。