我应该使用PREGET POST还是WP_QUERY

时间:2012-12-18 作者:user1609391

我在分类法中调用了以下查询。php模板通过query_brands_geo(\'dealers\', \'publish\', \'1\', $taxtype, $geo, $brands);

此功能工作正常。然而,在阅读了codex的查询帖子后,它提到pre\\u get\\u posts是更改默认查询的首选方式。pre\\u get\\u posts是否比下面的wp\\u查询功能更高效?

如果是这样,我将如何构造pre\\u get\\u posts并传递下面的变量和查询?

function my_custom_query($posttype, $poststatus, $paidvalue, $taxtype, $geo, $brands) {
   global $wp_query; 
   $wp_query = new WP_Query();
   $args = array( 
      \'post_type\' => $posttype, 
      \'post_status\' => array($poststatus), 
      \'orderby\' => \'rand\', 
      \'posts_per_page\' => 30, 
      \'meta_query\' => array( 
         array( 
            \'key\' => \'wpcf-paid\', 
            \'value\' => array($paidvalue), 
            \'compare\' => \'IN\', 
            ) 
      ), 
      \'tax_query\' => array( 
         \'relation\' => \'AND\', 
         array( 
            \'taxonomy\' => $taxtype, 
            \'field\' => \'slug\', 
            \'terms\' => $geo 
         ), 
         array( 
            \'taxonomy\' => \'brands\', 
            \'field\' => \'slug\', 
            \'terms\' => $brands 
         ) 
      ) 
   ); 

   return $wp_query->query($args); 
} 

3 个回复
最合适的回答,由SO网友:M-R 整理而成

pre_get_posts 将运行相同的查询,因此这两个查询将花费相同的时间。但是,如果你利用pre_get_posts 操作您将保存一个或多个SQL查询。现在,WordPress正在运行默认查询,然后您使用此函数运行查询,该函数将替换默认查询的结果(因此,默认查询没有任何用处)。下面是如何移动$args

function custom_pre_get_posts($query, $posttype=\'dealers\', $poststatus=\'publish\', $paidvalue=\'1\', $taxtype=\'any_default_value\', $geo=\'any_default_value\', $brands=\'any_default_value\') {

    // filter your request here.
    if($query->is_category) {

        $args = array(
            \'post_type\' => $posttype,
            \'post_status\' => array($poststatus),
            \'orderby\' => \'rand\',
            \'posts_per_page\' => 30,
            \'meta_query\' => array(
                array(
                    \'key\' => \'wpcf-paid\',
                    \'value\' => array($paidvalue),
                    \'compare\' => \'IN\',
                )
            ),
            \'tax_query\' => array(
                \'relation\' => \'AND\',
                array(
                    \'taxonomy\' => $taxtype,
                    \'field\' => \'slug\',
                    \'terms\' => $geo
                ),
                array(
                    \'taxonomy\' => \'brands\',
                    \'field\' => \'slug\',
                    \'terms\' => $brands
                )
            )
        );
        $query->query_vars = $args;
    }
}
add_action(\'pre_get_posts\', \'custom_pre_get_posts\');

SO网友:kaiser

迟到的回答是投票最多的回答,这会打断你的提问,在某些要点上根本不正确

WordPress内部首先使用WP\\u查询及其过滤器query_posts() (薄薄的包装WP_Query 那个shouldn\'t 在主题或插件中使用)来执行WP_Query. 这WP_Query 作为主循环/查询。此查询将运行大量过滤器和操作,直到生成实际的SQL查询字符串。其中之一是pre_get_posts. 其他是posts_clauses, posts_where, 等等also 允许您拦截查询字符串生成过程。

深入了解核心内部发生的情况

WordPress运行wp() 功能(inwp-includes/functions.php), 哪个呼叫$wp->main() ($wp 是WP类的对象,在中定义wp-includes/class-wp.php). 这告诉WordPress:

使用将URL解析为查询规范WP->parse_request() -- 下面将介绍更多信息使用$wp_query->parse_query() ($wp_query 是的对象class WP_Query, 定义于wp-includes/query.php). 请注意,尽管此函数的名称不同,在本例中WP_Query->parse_query 实际上并没有为我们做任何解析,因为这是由WP->parse_request().将查询规范转换为MySQL数据库查询,并在函数WP\\u query->get\\u posts()中运行数据库查询以获取帖子列表。将帖子保存在要在WordPress循环中使用的$wp\\u查询对象中来源Codex

结论

如果确实要修改主查询,那么可以使用多种过滤器。简单使用$query->set( \'some_key\', \'some_value\' );change 数据存在或使用$query->get( \'some_key\' );retrieve 进行条件检查的数据。这将避免您进行第二次查询altering 仅SQL查询。

如果你必须additional 查询,然后使用WP_Query 对象这将向数据库添加另一个查询。

示例

由于答案总是与示例配合得更好,因此这里有一个非常好的示例(Brad Touesnard的道具),它简单地扩展了核心对象,因此可以很好地重用(利用它制作插件):

class My_Book_Query extends WP_Query
{
    function __construct( $args = array() )
    {
        // Forced/default args
        $args = array_merge( $args, array(
            \'posts_per_page\' => -1
        ) );

        add_filter( \'posts_fields\', array( $this, \'posts_fields\' ) );

        parent::__construct( $args );
    }

    public function posts_fields( $sql )
    {
        return "{$sql}, {$GLOBALS[\'wpdb\']->terms}.name AS \'book_category\'";
    }
}
然后,您可以运行第二个附加查询,如以下示例所示。之后不要忘记重置查询。

$book_query = new My_Book_Query();
if ( $book_query->have_posts() )
{
    while ( $book_query->have_posts() )
    {
        $book_query->the_post();
        # ...do stuff...
    } // endwhile;
    wp_reset_postdata();
} // endif;

SO网友:fischi

请点击查看答案When to use WP_query(), query_posts() and pre_get_posts.

如果你有任何疑问,这是一个很好的资源。

结束

相关推荐

使用新的WP-Query()从循环中过滤后期格式;

嗨,我目前正在为我的博客构建一个主题。下面的代码指向最新的帖子(特色帖子)。因为这将有一个不同的风格比所有其他职位。然而我想过滤掉帖子格式:链接使用我在循环中定义的WP查询,因为它给我带来了更多的灵活性。我该怎么做呢? <?php $featured = new WP_Query(); $featured->query(\'showposts=1\'); ?> <?php while ($featured->have_post