问题描述

Codex 和 blogosphere 周围的教程中,有一半使用 query_posts(),一半使用 WP_Query 。这是怎么回事?

最佳解决方案

  •  query_posts()通过用查询的新实例替换来修改页面的主查询过于简单和有问题的方法。它是低效的 (re-runs SQL 查询),并将在一些情况下 (特别是经常处理帖子分页时) 会彻底失败。任何现代的 WP 代码都应该使用更可靠的方法,例如使用 pre_get_posts 钩子。 长话短说不要使用 query_posts();
  •  get_posts()在使用上非常相似,并接受相同的参数 (具有一些细微差别,如不同的默认值),但是返回数组,不会修改全局变量,并且可以安全地在任何位置使用;
  •  WP_Query 类功能在幕后,但您也可以创建和使用自己的对象。位更复杂,限制较少,也可以随时随地使用。

次佳解决方案

 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_postsWP_Query 是构建辅助查询 (如静态首页上的相关帖子,滑块,精选内容和内容) 的正确方法。应该注意的是,您不应该使用主页,单页或任何类型的归档页面中的主要查询中的任何一个,因为它会破坏页面功能。如果需要修改主查询,请使用 pre_get_posts 来做,而不是自定义查询。 (更新:对于静态前页和真实页面,请参阅 Using pre_get_posts on true pages and static front pages *)

实质上,WP_Query 主要用于查询,也由 get_posts 使用,但 get_posts()虽然使用 WP_Query,但有一些差异

  •  get_postsWP_Query 快。利润率取决于网站总数量。其原因是 get_posts 默认通过'no_found_rows' => true WP_Query 跳过/合法分页。使用'no_found_rows' => trueWP_Query 获取查询的帖子数量,然后缓存,默认情况下,它进一步搜索与查询匹配的所有帖子,以便计算分页。因此,get_posts()只能用于非分页查询。分页 get_posts 真是一大难题。 WP_Query 应用于所有分页查询
  •  get_posts()不受 posts_*过滤器的影响,WP_Query 会受到这些过滤器的影响。原因是 get_posts 默认通过'suppress_filters' => trueWP_Query
  •  get_posts 具有几个额外的参数,如 includeexcludenumberpostscategory 。在传递给 WP_Query 之前,将这些参数更改为 WP_Query 的有效参数。 include 变为 post__inexclude 转化为 post__not_incategory 转化为 catnumberposts 转化为 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' => 1WP_Query,默认情况下 get_posts 忽略粘帖

基于上述,是否使用 get_postsWP_Query 取决于您,您从查询中实际需要什么。以上应引导您选择

第三种解决方案

基本的区别是 query_posts()真的只是为了修改当前的 Loop 。一旦完成,就需要重新设置循环并以快捷的方式发送。这个方法也更容易理解,只是因为你的”query” 基本上是一个你传递给函数的 URL 字符串,像这样:

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

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

我更倾向于使用 WP_Query,因为它会发生。真的,这将会归结于你的具体情况。

第四种方案

没有必要使用 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 课程。

第五种方案

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

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。