似乎法典和博客圈中的一半教程使用query_posts(),一半使用WP_Query。怎么了?

评论

还要检查此较长的分析

#1 楼


query_posts()过于简单,而且是通过用查询的新实例替换页面的主查询来修改页面的主查询的一种有问题的方式。它效率低下(重新运行SQL查询),并且在某些情况下(特别是在处理帖子分页时,通常会完全失败)。为此,任何现代WP代码都应使用更可靠的方法,例如使用pre_get_posts钩子。 TL; DR永远不要使用query_posts()。
get_posts()的用法非常相似,接受相同的参数(有些细微差别,例如不同的默认值),但是返回一个数组,不修改全局变量并且可以在任何地方安全使用。
WP_Query是在后台提供强大支持的类,但是您也可以创建和使用自己的实例。更加复杂,限制更少,在任何地方都可以安全使用。



评论


@jjeaton query_posts()是WP_Query的微型包装函数,它唯一要做的事情(按照流程图)是覆盖全局$ wp_query

–稀有
2011年8月8日15:39

@jjeaton用WP_Query替换query_posts()不会提高性能,原始页面的查询仍将运行,因为这是核心负载的一部分。即使模板文件完全没有循环,这些查询也将运行。

–稀有
2011年8月8日17:15



无法摆脱这是WPSE上最聪明,最受好评的帖子的感觉。也应该在食典中。

– kaiser
2011年9月16日下午0:03

我将添加对“ query_posts()的性能”问题的最清楚的描述:在模板文件中使用query_posts()或WP_Query将具有相同的性能成本:刚刚执行的查询。 Codex文章中讨论的问题是,如果您实际上要替换查询,则应使用“ parse_query”过滤器过滤原始的query_posts()来进行替换。这样,您只有一个原始的,理想的查询,而不必进行第二个查询来笨拙地替换它。 query_posts()永远不可能!决不!

–jerclarke
2012年4月19日在22:24

约翰·詹姆斯·雅各比(John James Jacoby)在developer.wordpress.com博客上对query_posts做出了令人敬畏的惊人解释,这些解释使所有这些答案无所适从。要点:query_posts根本不修改主循环,它在运行后将其替换。修改主循环的最佳方法是通过pre_get_posts过滤器。 developer.wordpress.com/2012/05/14/…

–丹·盖尔(Dan Gayle)
2012年6月9日23:10



#2 楼

query_posts-永远不要使用query_posts。除了@Rarst所说的以外,query_posts的真正大问题是,它破坏了主查询对象(存储在$wp_query中)。许多插件和自定义代码都依赖于主查询对象,因此破坏主查询对象意味着您正在破坏插件和自定义代码的功能。所有重要的分页功能只是其中一个这样的功能,因此,如果您破坏主查询,则会中断分页。
要证明query_posts的糟糕程度,在任何模板上,请执行以下操作并比较结果。

get_postsWP_Query是构造辅助查询(如相关帖子,滑块,特色内容和静态首页上的内容)的正确方法。应该注意的是,您不应该使用这两种方法中的任何一种来支持主页,单页或任何类型的存档页面上的主查询,因为这会破坏页面功能。如果需要修改主查询,请使用pre_get_posts进行修改,而不要使用自定义查询。 (更新:对于静态首页和真实页面,请参阅在真实页面和静态首页上使用pre_get_posts *)有一些区别


WP_Queryget_posts更快。保证金取决于网站的总帖子数。原因是,get_posts()默认将WP_Query传递给get_posts,从而跳过/合法地中断了分页。使用WP_Query时,get_posts获取查询的帖子数量,然后释放,默认情况下,它将进一步搜索与查询匹配的所有帖子以计算分页。
因此,对于非分页查询应使用'no_found_rows' => true只要。对WP_Query进行分页确实是一团糟。 'no_found_rows' => true应该用于所有分页查询


WP_Query不受get_posts()滤波器的影响,而get_posts受这些滤波器的影响。原因是WP_Query默认情况下将get_posts()传递给posts_*


WP_Query还有几个额外的参数,例如get_posts'suppress_filters' => trueWP_Queryget_posts。在传递给include之前,确实会将这些参数更改为exclude的有效参数。将numberposts更改为category,将WP_Query更改为WP_Query,将include 更改为post__in,然后将exclude更改为post__not_in。请注意,所有可以传递给category的参数都可以与cat一起使用,您可以忽略并且不使用numberposts的默认参数。


posts_per_page仅返回WP_Queryget_posts属性,而get_posts返回完整的对象。当涉及可在循环内使用的条件,分页和其他有用信息时,此对象非常有用。


get_posts不使用循环,而是显示$posts循环帖子。另外,默认情况下没有模板标签可用。 WP_Query必须用于使模板标签可用。 WP_Query使用循环,并且默认情况下模板模板可用。上面的内容是由您决定使用get_posts还是foreach,您实际上需要从查询中获得什么。以上内容将指导您进行选择

评论


我希望我能喜欢答案。这解释了很多。

– Athoxx
17年6月12日在7:17

很好的解释! “ get_posts()仅应用于非分页查询。将get_posts分页确实是一大麻烦。WP_Query应该用于所有分页查询”基本上是所有需要了解imo的人。

–布林
18年4月19日在19:27



#3 楼

基本区别是query_posts()实际上仅用于修改当前回路。完成后,有必要重置循环并以愉快的方式发送循环。只是因为您的“查询”基本上是您传递给函数的URL字符串,所以该方法也更易于理解,如下所示:

query_posts('meta_key=color&meta_value=blue'); 


另一方面,WP_Query更像是一种通用工具,比query_posts()更像直接编写MySQL查询。您还可以在任何地方(不仅是在循环中)使用它,并且它不会干扰任何当前正在运行的帖子查询。

由于发生这种情况,我倾向于更频繁地使用WP_Query。确实,这取决于您的具体情况。

#4 楼

根本不需要使用query_posts()。它所做的就是实例化一个新的WP_Query对象,并将该新对象重新分配给global wp_query

以下为实际的query_posts()函数供参考。

 function query_posts($query) {
        $GLOBALS['wp_query'] = new WP_Query();
        return $GLOBALS['wp_query']->query($query);
    }


如果要创建深度自定义查询脚本,请实例化自己的WP_Query对象。或使用get_posts()(如果您需要做的只是在这里和那里进行一些灯光操纵)。

无论哪种情况,我都强烈建议您帮个忙,转到wp_includes/query.php并仔细研究WP_Query类。

#5 楼

请确保在使用wp_reset_query()之后再使用query_posts(),因为它也会影响其他查询结果。

#6 楼

如果我记得没看错的话,本质上,“循环”就是在核心文件中执行WP_Query,但是以一种更易于理解的方式进行。

#7 楼



query_posts():仅在需要修改主查询的情况下才可以使用。它设置了很多全局变量;


get_posts():它在机制上非常相似并且接受相同的参数,但是返回帖子数组


WP_Query:您可以创建并使用其自己的对象。位更复杂,限制更少,可以在任何地方使用。