wordpress中的2个查询方法query_posts() 和WP_Query 到底有什么区别和联系?分别应该在什么情形下使用?
各种博客教程中2种方法都有涉及,但是没有明确区分,让人比较困惑,这个问题怎么破?
主流的理解思路
query_posts() 过于简单并且存在问题,通过用查询的新实例替换页面的主查询来修改主查询。相对来说这个函数效率较低下(re-runs SQL查询),并在某些情况下可能会彻底失败(特别是在处理帖子分页时)。任何当前的WP代码都应该使用更可靠的方法,例如使用pre_get_posts 挂钩。 长话短说尽量不要使用 query_posts();
get_posts() 在用法上非常相似,并且接受相同的参数(具有一些细微差别,如不同的默认值),但返回帖子数组,不修改全局变量并且可以安全地在任何地方使用;
WP_Query 类既支持后台默认流程,也可以自己创建和使用它的对象。用法更复杂,限制更少,也可以安全地在任何地方使用。
次佳解决思路
query_posts – 您永远不应该使用query_posts 。除了上文所说的,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 来完成,而不是自定义查询。 (更新:对于静态首页和真实页面,请参阅Using pre_get_posts on true pages and static front pages *)
实质上,WP_Query 由主查询使用,也由get_posts 使用,但虽然get_posts() 使用WP_Query ,但有一些差异
get_posts 比WP_Query 更快。区别取决于网站的总帖子数量。原因是,get_posts 默认将'no_found_rows' => true 传递给WP_Query ,WP_Query 会跳过/合法地中断分页。使用'no_found_rows' => true ,WP_Query 获取查询的帖子数量,然后保留,默认情况下,它会进一步搜索与查询匹配的所有帖子以计算分页。因此,get_posts() 只能用于非分页查询。分页get_posts 真的是一个大混乱。 WP_Query 应该用于所有分页查询
get_posts() 不受被WP_Query 影响的posts_* 过滤器的影响。原因是get_posts 默认将'suppress_filters' => true 传递给WP_Query
get_posts 有几个额外的参数,如include ,exclude ,numberposts 和category 。在传递给WP_Query 之前,这些参数会变为WP_Query 的有效参数。 include 变为post__in ,exclude 变为post__not_in ,category 变为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() 实际上只是用于修改当前循环。一旦你完成了,有必要重新设置循环并将其快速发送。这个方法也比较容易理解,因为你的”query”基本上是一个URL字符串,你传递给函数,如下所示:
query_posts('meta_key=color&meta_value=blue');
另一方面,WP_Query 更像是一种通用工具,更像是直接编写MySQL查询,而不是query_posts() 。你也可以在任何地方使用它(不只是在循环中),它不会干扰任何当前正在运行的后期查询。
第四种思路
根本不需要使用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() ,如果你需要做的只是一些轻微的操纵。
参考资料
- When should you use WP_Query vs query_posts() vs get_posts()?
|