问题描述

我有一个显示 home.php 模板的主页,其中包含 2 个带有小工具的侧边栏。

主要的查询仍然是标准的 10 个帖子,但是由于我没有显示这些信息,所以我想彻底消除对数据库的查询。如果需要的话,一个空的循环将会做,因为我没有使用 home.php 模板中的主循环。

我该怎么做?我可以使用 pre_get_posts 来最大限度地减少和减少查询,但仍然让我有一个非常快的查询,我该如何完全消除它?

最佳解决方案

posts_request 过滤器

通过 WP_Query 扫描,我们发现这一部分感兴趣:

if ( !$q['suppress_filters'] ) {
    /**
     * Filter the completed SQL query before sending.
     *
     * @since 2.0.0
     *
     * @param array    $request The complete SQL query.
     * @param WP_Query &$this   The WP_Query instance (passed by reference).
     */
      $this->request = apply_filters_ref_array( 'posts_request',
          array( $this->request, &$this ) );
   }

   if ( 'ids' == $q['fields'] ) {
       $this->posts = $wpdb->get_col( $this->request );
       $this->posts = array_map( 'intval', $this->posts );
       $this->post_count = count( $this->posts );
       $this->set_found_posts( $q, $limits );
       return $this->posts;
   }

我们可能会尝试通过 posts_request 过滤器消除主要的家庭请求。以下是一个例子:

add_filter( 'posts_request', function( $request, WP_Query $q )
{
    // Target main home query
    if ( $q->is_home() && $q->is_main_query() )
    {
        // Our early exit
        $q->set( 'fields', 'ids' );

        // No request
        $request = '';
    }

    return $request;

}, PHP_INT_MAX, 2 );

在那里我们迫使'fields' => 'ids'提前退出。

posts_pre_query 过滤器 (WP 4.6+)

我们还可以使用新的 posts_pre_query src 滤镜,可在 WordPress 4.6+

add_filter( 'posts_pre_query', function( $posts, WP_Query $q )
{
    if( $q->is_home() && $q->is_main_query() )
    {
        $posts = [];
        $q->found_posts = 0;
    }
    return $posts;
}, 10, 2 );

此过滤器可以跳过通常的数据库查询来实现自定义帖子注入。

我刚刚测试了这一点,注意到这不会阻止粘贴的帖子,与 posts_request 方法相反。

查看更多信息 #36687 的机票和 @boonebgorges 的 example there

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。