我在分类法中调用了以下查询。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);
}
最合适的回答,由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;