什么时候应该使用WP_Query vs query_posts()vs get_posts()?
-
-
还要检查此[较长的分析](http://wordpress.stackexchange.com/questions/226960/why-query-posts-isnt-marked-as-deprecated/248955#248955)Check also this [longer analysis](http://wordpress.stackexchange.com/questions/226960/why-query-posts-isnt-marked-as-deprecated/248955#248955)
- 1
- 2016-12-25
- prosti
-
7 个回答
- 投票数
-
- 2010-09-13
-
query_posts()
过于简单和通过用查询的新实例替换页面的主查询的一种有问题的方式来修改页面.它效率低下(重新运行SQL查询),并且在某些情况下(特别是在处理帖子分页时,通常会完全失败).任何现代WP代码都应使用更可靠的方法,例如使用pre_get_posts
挂钩. TL; DR 永远不要使用query_posts(). -
get_posts()
在用法上非常相似并接受相同的参数(有一些细微差别,例如不同的默认值),但是返回一个帖子数组,不修改全局变量,并且可以在任何地方使用. -
WP_Query
是同时支持这两个功能的类场景,但是您也可以创建和使用自己的实例.更加复杂,限制更少,在任何地方都可以安全使用.
query_posts()
is overly simplistic and a problematic way to modify the main query of a page by replacing it with new instance of the query. It is inefficient (re-runs SQL queries) and will outright fail in some circumstances (especially often when dealing with posts pagination). Any modern WP code should use more reliable methods, like making use of thepre_get_posts
hook, for this purpose. TL;DR don't use query_posts() ever.get_posts()
is very similar in usage and accepts the same arguments (with some nuances, like different defaults), but returns an array of posts, doesn't modify global variables and is safe to use anywhere.WP_Query
is the class that powers both behind the scenes, but you can also create and work with your own instance of it. A bit more complex, fewer restrictions, also safe to use anywhere.
-
(1)"并且可以在任何地方安全使用"->但不要在MAIN循环中使用它.(2)记住使用全局$ query_string;在具有query_posts()的行之前;(1) "and is safe to use anywhere" --> but do not use this for the MAIN loop. (2) remember to use global $query_string; before the line that has query_posts();
- 1
- 2011-02-19
- edelwater
-
@scribu,然后再次执行"get_posts"将起作用,尽管不建议这样做:http://core.trac.wordpress.org/ticket/16545@scribu then again 'get_posts' will work although not advised: http://core.trac.wordpress.org/ticket/16545
- 1
- 2011-02-19
- edelwater
-
我相信query_posts的效率也较低,因为它将运行其他查询,如果如果仅将WP_Query用作主循环,则它将仅运行在WP_Query中选择的查询.I believe that `query_posts` is also less efficient in that it will run additional queries, when if you use only `WP_Query` for your main loop, it will only run the query you choose in WP_Query.
- 1
- 2011-08-08
- jjeaton
-
@jjeaton`query_posts()`是WP_Query`的微型包装函数,它唯一要做的额外工作(按照流程图)是覆盖全局`$ wp_query`.@jjeaton `query_posts()` is tiny wrapper function for `WP_Query`, the only extra thing it does (as per flowchart) is overwriting global `$wp_query`
- 10
- 2011-08-08
- Rarst
-
@Rarst我指的是[query_posts的法典中的本节](http://codex.wordpress.org/Function_Reference/query_posts#Additional_SQL_Queries),但是,我可能会误认为对性能的影响.除非在模板文件中使用WP_Query也会得到相同的结果(即丢弃查询并重新执行)@Rarst I was referring to [this section in the Codex for query_posts](http://codex.wordpress.org/Function_Reference/query_posts#Additional_SQL_Queries) however, I may be mistaken regarding the effect on performance. Unless using WP_Query in your template file will also have the same result (i.e. throwing away your query, and re-executing)
- 1
- 2011-08-08
- jjeaton
-
@jjeaton用`WP_Query`替换`query_posts()`不会影响性能,原始页面的查询仍将运行,因为这是核心负载的一部分.即使模板文件根本没有循环,这些查询也将运行.@jjeaton Replacing `query_posts()` with `WP_Query` will make no difference in performance, original page's query will still run because that is part of core load. Those queries will run even if your template file has no loop at all.
- 9
- 2011-08-08
- Rarst
-
无法摆脱这是WPSE上最聪明,最受好评的帖子的感觉.也应该在食典中.Can't get rid off the feeling that this the most genious and upvoted post on WPSE. Should be in Codex as well.
- 122
- 2011-09-16
- kaiser
-
好的,在看了很长时间之后,我认为`query_posts()`缺少一个静态变量,该变量在第一次使用后会被设置为true,并且-如果使用两次-应该触发`_doing_it_wrong();`.猜猜我将为此烦扰wp-hacker或trac家伙.Ok, after looking at it for more than quite a time, I think `query_posts()` is missing a static var that get's set to true after the first use and - if used twice - should trigger `_doing_it_wrong();`. Guess I'm going to bug the wp-hacker or trac guys about this.
- 1
- 2011-09-16
- kaiser
-
@kaiser好...两次使用`query_posts()`大约和一次一样糟糕,对我来说并没有多大关系.:)顺便说一下,安德鲁·纳辛(Andrew Nacin)将就查询做演讲,他说他可能会对流程图提出一些改进,因此第二版可能会在将来的某个时候发布.@kaiser well... using `query_posts()` twice is about as bad as once, doesn't matter much as for me. :) btw Andrew Nacin is going to do presentation on queries and he said he might propose some improvements to the flowchart, so version two might be coming some time in the future.
- 1
- 2011-09-16
- Rarst
-
我将添加对" query_posts()的性能"问题的最清楚的描述:在模板文件中使用query_posts()或WP_Query将具有相同的性能成本:刚刚执行的查询.Codex文章中讨论的问题是,如果您实际上要替换查询,则应使用"parse_query"过滤器过滤原始的query_posts()来进行替换.这样,您只有一个原始的理想查询,而不必进行第二个查询来笨拙地替换它.query_posts()永远不可能!决不!I'll just add my clearest description of the "performance of query_posts()" issue: Using query_posts() or WP_Query within a template file will have the same performnace cost: the query you just performed. The issue discussed in the codex article is that if you actually want to replace the query you should do so by filtering the original query_posts() with the 'parse_query' filter. That way you only have the one, original, desirable query, rather than doing a second query to awkwardly replace it. query_posts() is NEVER THE WAY!! NEVER!
- 9
- 2012-04-19
- jerclarke
-
这没有提及"请求"过滤器,这是修改主查询的好方法.与query_posts相比,优点是该函数清除了原始查询并生成了一个新查询-就像您使用WP_Query一样.通过使用请求过滤器,您可以在发送原始查询之前对其进行修改.我认为那就是@JeremyClarke在上面的意思.This makes no mention of the 'request' filter, which is a great way to modify the main query. The advantage over query_posts is that function wipes out the original query and generates a new one - same as if you used WP_Query. By using the request filter, your modifying the original query before its ever sent. I think thats what @JeremyClarke is getting at above.
- 1
- 2012-05-02
- eddiemoya
-
约翰·詹姆斯·雅各比(John James Jacoby)在developer.wordpress.com博客上对query_posts做出了令人敬畏的惊人解释,这些解释使所有这些答案无所适从.要点:" query_posts"根本不"修改"主循环,而是在它已经运行之后"替换"它.修改主循环的最佳方法是通过`pre_get_posts`过滤器. http://developer.wordpress.com/2012/05/14/querying-posts-without-query_posts/There's a freaking awesome explanation of query_posts written by John James Jacoby on the developer.wordpress.com blog that blows all of these answers out of the water. The main point: `query_posts` doesn't *modify* the main loop at all, it *replaces* it *after* it has already run. The best way to modify the main loop is through a `pre_get_posts` filter. http://developer.wordpress.com/2012/05/14/querying-posts-without-query_posts/
- 23
- 2012-06-09
- Dan Gayle
-
@Dan,您混淆了技术实施和目的.query_posts()确实替代了主循环对象,但其目的是修改主循环.我也很喜欢环路滤波器,但这不是问什么.关于该主题还有其他人的跟进问题.@Dan you are confusing technical implementation and purpose. `query_posts()` does replace main loop object, but the purpose of it is to modify main loop. Also I am warmly fond of loop filters, but that wasn't what question asked. There is follow up question from other person on that topic.
- 3
- 2012-06-10
- Rarst
-
问题是"什么时候应该使用... query_posts()",根据该博客文章和上面的评论提供的逻辑,答案可能永远不会.The question was "When should you use... query_posts()" and according to the logic presented by that blog post and the comments above, the answer is likely never.
- 2
- 2012-06-11
- Dan Gayle
-
那么,如果是如此糟糕,为什么存在query_posts呢?so, if its so bad, why does `query_posts` exist?
- 2
- 2012-09-10
- Manny Fleurmond
-
@Manny Fleurmond从概念上讲," query_posts()"是一种将主循环概念降低到主题模板标签级别的尝试(减轻难度是WP流行的强项之一).结果证明,对于模板标签来说,完成任务实在太多了.核心开发人员确实表达了过时的可能性,但我认为还没有决定.@Manny Fleurmond conceptually `query_posts()` is an attempt to dumb down main loop concepts to the level of theme template tag (ease of which is one of the strong points for WP popularity). The task simply turned out to be too much for template tag to possibly accomplish. Core developers did voice possibility of it getting deprecated but I don't think there was decision about that yet.
- 1
- 2012-09-10
- Rarst
-
您实际上无法"在任何地方使用" WP_Query(),我刚刚尝试过,但它仍然在$thequery-> have_posts()上崩溃,无限递归,请参阅http://wordpress.stackexchange.com/questions/34270You actually can't "use anywhere" the WP_Query(), i just tried and it still croaks at $thequery->have_posts(), infinite recursion, see http://wordpress.stackexchange.com/questions/34270
- 1
- 2014-10-21
- NoBugs
-
@NoBugs该问题中的循环是错误的,并且有解释原因的答案.@NoBugs the loop in that question is wrong and there is answer explaining why.
- 1
- 2014-10-21
- Rarst
-
Agghh对此表示感谢.最后,有道理.认真地说,WordPress及其糟糕的文档.我不知道这种复杂的软件和糟糕的编码标准是如何变得如此流行.Agghh thanks for this. Finally, something makes sense. Seriously, WordPress and their lousy documentation. I don't know how such convoluted software and bad coding standards became so popular.
- 1
- 2015-04-16
- racl101
-
在wp_query和get_posts http://www.wpclocked.com/之间发现了这种速度测试Found this speed test between wp_query and get_posts http://www.wpclocked.com/
- 1
- 2015-07-18
- Anagio
-
我相信这样的测试...完全没有.:)该函数是一个_very_薄包装器,任何区别都将来自参数和/或挂钩的细微差别.I would trust such test... exactly none. :) The function is a _very_ thin wrapper, any difference will be coming from slight difference in arguments and/or hooks.
- 1
- 2015-07-19
- Rarst
-
不需要情绪,query_posts()是一个具有副作用的函数:设置全局变量.WordPress的功能错开了.这不是性能问题,而是代码质量问题.查看https://developer.wordpress.org/reference/functions/query_posts/,看看query_posts做什么.除非要弄乱全局变量,否则请使用WP_Query.No need for emotions, query_posts() is a function with side effects: setting a global. WordPress is staggerd with functions with side effects. This is not a performance issue but a quality of code issue. Look at https://developer.wordpress.org/reference/functions/query_posts/ and see what query_posts does. Use WP_Query unless you want to mess up global variables.
- 0
- 2020-03-14
- user718960
-
- 2015-06-18
query_posts
-您永远不要使用query_posts
.除了@Rarst所说的以外,query_posts
的真正大问题是,它破坏了主查询对象(存储在$ wp_query
中).许多插件和自定义代码都依赖于主查询对象,因此破坏主查询对象意味着您正在破坏插件和自定义代码的功能.所有重要的分页功能只是其中一个功能,因此,如果中断主查询,则会中断分页.要证明
query_posts
在任何模板上有多糟糕,请执行以下操作并比较结果var_dump($ wp_query); query_posts('&posts_per_page=-1'); var_dump($ wp_query);
get_posts
和WP_Query
是构造次要查询的正确方法(类似的相关帖子,滑块,特色内容和静态首页上的内容).应该注意的是,您不应使用这两种方法中的任何一种来支持主页,单页或任何类型的存档页面上的主查询,因为这会破坏页面功能.如果需要修改主查询,请使用pre_get_posts
进行修改,而不要使用自定义查询. ( 更新: 有关静态首页和真实页面,请参见使用pre_get_posts在真实页面和静态首页上 *)本质上,主查询使用
WP_Query , get_posts
也使用WP_Query
,但是尽管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'=>.true
到WP_Query
-
get_posts
有几个额外的参数,例如include
,exclude
,numberposts
和类别
.在将这些参数传递给WP_Query
之前,确实将其更改为WP_Query
的有效参数.include
更改为post__in
,Exclude
更改为post__not_in
,类别
更改为cat
和numberposts
放入posts_per_page
.请注意,所有可以传递给WP_Query
的参数与get_posts
一起使用,您可以忽略和不使用get_posts
-
get_posts
仅返回WP_Query
的$posts
属性,而WP_Query
返回完整对象.当涉及条件,分页和可在循环内使用的其他有用信息时,该对象非常有用. -
get_posts
不使用循环,而是使用foreach
循环显示帖子.另外,默认情况下没有模板标签可用.必须使用setup_postdata($post)
使模板标签可用.WP_Query
使用循环,并且默认情况下模板模板可用 -
get_posts
通过'ignore_sticky_posts'=> 1
到WP_Query
,因此默认情况下get_posts
会忽略粘性帖子
基于上述内容,您可以使用
get_posts
还是WP_Query
以及查询中实际需要的内容.以上内容将指导您进行选择query_posts
- You should never ever usequery_posts
. Apart from what @Rarst has said, the really big issue withquery_posts
is, it breaks the main query object ( stored in$wp_query
). A lot of plugins and custom code relies on the main query object, so breaking the main query object means that you are breaking the functionalities of plugins and custom code. Just one such function is the all important pagination function, so if you break the main query, you break pagination.To prove how bad
query_posts
is, on any template, do the following and compare the resultsvar_dump( $wp_query ); query_posts( '&posts_per_page=-1' ); var_dump( $wp_query );
get_posts
andWP_Query
are the correct way to construct secondary queries ( like related posts, sliders, featured contentand content on static front pages) with. It should be noted, you should not use any of the two in favor of the main query on the home page, single page or any type of archive page as it will break page functionality. If you need to modify the main query, usepre_get_posts
to do so, and not a custom query. (UPDATE: For static front pages and true pages, see Using pre_get_posts on true pages and static front pages*)In essence,
WP_Query
is used by the main query and is also used byget_posts
, but althoughget_posts()
usesWP_Query
, there are a few differencesget_posts
are faster thanWP_Query
. The margin depends on the amount of total posts of the site. The reason for this is,get_posts
passes'no_found_rows' => true
by default toWP_Query
which skips/legally breaks pagination. With'no_found_rows' => true
,WP_Query
gets the amount of posts queried, then bails out, where by default, it further search for all posts matching the query in order to calculate pagination.For this reason,
get_posts()
should be used for non paginated queries only. Paginatingget_posts
is really one big mess.WP_Query
should be used for all paginated queriesget_posts()
aren't influenced by theposts_*
filters whereWP_Query
gets influenced by these filters. The reason is thatget_posts
, by default, passes'suppress_filters' => true
toWP_Query
get_posts
has a couple of extra parameters likeinclude
,exclude
,numberposts
andcategory
. These parameters do get changed into valid parameters forWP_Query
before being passed toWP_Query
.include
gets changed intopost__in
,exclude
intopost__not_in
,category
intocat
andnumberposts
intoposts_per_page
. Just a note, all of the parameters that can be passed toWP_Query
works withget_posts
, you can ignore and not use the default parameters ofget_posts
get_posts
returns just the$posts
property ofWP_Query
whileWP_Query
returns the complete object. This object is quite useful when it comes to conditionals, pagination and other useful info that can be used inside the loop.get_posts
doesn't use the loop, but aforeach
loop to display posts. Also, no template tags are available by default.setup_postdata( $post )
has to be used to make the template tags available.WP_Query
uses the loop and template tags are available by defaultget_posts
passes'ignore_sticky_posts' => 1
toWP_Query
, soget_posts
by default ignores sticky posts
Based on the above, whether to use
get_posts
orWP_Query
is up to you and what do you actually need from the query. The above should guide you in your choice-
我希望我能喜欢答案.这解释了很多.I wish I could favorite answers. This explains so much.
- 2
- 2017-06-12
- Athoxx
-
很好的解释! "get_posts()仅应用于非分页查询.将get_posts分页确实是一大麻烦.WP_Query应该用于所有分页查询"基本上是所有需要了解imo的人.Great Explanation! "get_posts() should be used for non paginated queries only. Paginating get_posts is really one big mess. WP_Query should be used for all paginated queries" Is basically all someone needs to know imo.
- 2
- 2018-04-19
- Bullyen
-
- 2010-09-13
基本区别是
query_posts()
实际上仅用于修改当前Loop.完成后,有必要重置循环并以愉快的方式发送循环.仅仅因为您的"查询"基本上是您传递给函数的URL字符串,这种方法也更易于理解,就像这样:query_posts('meta_key=color&meta_value=blue');
另一方面,与
query_posts()
相比,query_posts()
更像是一种通用工具,更像直接编写MySQL查询.您还可以在任何地方(不仅是在循环中)使用它,它不会干扰任何当前正在运行的帖子查询.随着时间的流逝,我倾向于更频繁地使用
query_posts()
.确实,这取决于您的具体情况.The basic difference is that
query_posts()
is really only for modifying the current Loop. Once you're done it's necessary to reset the loop and send it on its merry way. This method is also a little easier to understand, simply because your "query" is basically a URL string that you pass to the function, like so:query_posts('meta_key=color&meta_value=blue');
On the other hand,
WP_Query
is more of a general purpose tool, and is more like directly writing MySQL queries thanquery_posts()
is. You can also use it anywhere (not just in the Loop) and it doesn't interfere with any currently running post queries.I tend to use
WP_Query
more often, as it happens. Really, it's going to come down to your specific case. -
- 2013-07-13
根本不需要使用
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
类.There is simply no need to use
query_posts()
. All it does is instantiates a new WP_Query object and reassigns that new object toglobal wp_query
.For reference, the following is that actual
query_posts()
function.function query_posts($query) { $GLOBALS['wp_query'] = new WP_Query(); return $GLOBALS['wp_query']->query($query); }
Instantiate your own WP_Query object if you want to create an in depth custom query script. Or use
get_posts()
if all you need to do is some light manipulation here and there.In either case, I highly recommend doing yourself a favor and going to
wp_includes/query.php
and perusing theWP_Query
class. -
- 2013-07-08
请确保在使用
wp_reset_query()
后再使用query_posts()
,因为这也会影响其他查询结果.Make sure that you use
wp_reset_query()
after usingquery_posts()
because it will affect other query result also. -
-
- 2017-07-19
- query_posts():只有在需要修改main的情况下才可以使用查询.它设置了很多全局变量;
- get_posts():在机制上非常相似,接受相同的参数,但返回数组的帖子
- WP_Query :您可以创建并使用其自己的对象.位更加复杂,限制更少,可以在任何地方使用.
- query_posts(): might be used in one and only case if you need to modify main query . It sets a lot of global variables;
- get_posts(): it is very similar in mechanics and accepts same arguments, but returns array of posts
- WP_Query: you can create and work with own object of it. Bit more complex, less restrictions, it is safe to use anywhere.
Codex 和博客圈中的一半教程似乎都使用
query_posts()
,一半使用WP_Query
.怎么了?