在讲WP_Query之前我们要先区分一下两个名词:
- WP_Query是Wordpress自带的的一个用于处理复杂请求的类(这里的请求的内容不仅包括文章,还可能是页面,用户,分类等其它信息)。
- $wp_query则是在wp-blog-header.php文件中定义的一个WP_Query实体对象,它提供了当前请求的信息。
访问Wordpress首页或分类页面的时候,Wordpress默认创建一个WP_Query的实例,做为这个页面的主循环。 在查看Wordpress主题源代码时,你经常会看到类似:while( have_posts() ) : the_post(); 的代码。这个就是查找本页面主循环中是否有文章,并予以显示的方法。不过很多时候,除了页面的主循环,我们可以还需要创建自己的查询对象,比方用来显示热门的文章、某人的特定文章等时候。
这里我们主要讲一下WP_Query类有哪些方法和属性。官方文档中,优先描述的是WP_Query的属性,但我觉得从方法入手,更容易让用户理解。
方法
WP_Query类接受一个string或数组类型的查询条件做为其构造函数,除去了它的构造函数,WP_Query内部还包含了13个函数,它们的作用分别如下:
init(): 类内部的初始化函数(注意,不是构造函数),用于初始化对象,清空所有的属性(设为null, 0 或 False)。
parse_query( $query ): parse_query接受一个String类型查询字符串,并将解析后得到的参数赋给类本身。当构造函数中传入的为string类型的参数时,这个方法分被调用,并将string类型的参数转化为数组结构。
parse_query_vars():本身并没做实际工作,只是重新解析了上一个查询函数。相当于调用了不带参数的parse_query。(实际上,源码里就是这么实现的)。
get( $query_var ), set( $query_var, $value ): 单独设置或获取查询条件中的某个属性。不想写一长串难读的查询条件的话,不妨试试用set函数。
&query($query) , &get_posts(): query用于接受查询条件,并从数据库中查找相应的内容。如果内容是文章,第二个方法get_posts则可以用来返回这些文章。注意调用get_posts的同时,会更改对象中的$posts and $post_count两个参数。
have_posts(), the_post(), next_post(), rewind_posts(): WP_Query在查询的时候,会创建一个队列,队列中包含所有查到的文章。这4个方法就是用来对队列进行操作的。名字一目了然,have_posts判断队列中是否还有文章,有的话the_post则拿到当前的文章,next_post让队列向后移一位,rewind_posts则是返回到队列的最开头。
get_queried_object(), get_queried_object_id(): 最开始我们就说过,WQ_Query不仅用来查询文章和页面,还可以用来查询用户、分类等其它信息。这两个方法就是用来判断当前查询的对象,并返回对象或对象的ID。
属性
了解了上面的方法,属性就不难理解了。
$query, $query_vars: WP_Query的查询条件。$query为字符串格式, $query_vars为解析后的数组格式。
$queried_object, $queried_object_id: 对应get_queried_object()和get_queried_object_id()方法。可能是文章、页面、用户、分类。
$posts: 所有被查到的文章。
$post_count, $found_posts, $max_num_pages: 分别为文章总数,查询到的文章数,总页数。
$current_post,$post: 当前文章的序列数和当前的Post对象。
其它的属性还包括:$is_single, $is_page, $is_archive, $is_preview, $is_date, $is_year, $is_month, $is_time, $is_author, $is_category, $is_tag, $is_tax, $is_search, $is_feed, $is_comment_feed, $is_trackback, $is_home, $is_404, $is_comments_popup, $is_admin, $is_attachment, $is_singular, $is_robots, $is_posts_page, $is_paged。通过其名字,基本可以看出它的含义,就不多解释了。
实例
只通过上面的说明,你可能很难知道如何去使用WP_Query,下面我们就通过几个实例让大家更好的了解它。
通过作者获取文章
查询单个作者的文章
根据ID来查找。
$query = new WP_Query( 'author=123' );
根据用户名查找。
$query = new WP_Query( 'author_name=rami' );
查询多个人的文章
$query = new WP_Query( 'author=2,6,17,38' );
查询不属于某个人的文章
可以通过减号“-”来排除某位作者。
$query = new WP_Query( 'author=-12' );
通过分类目录查找
查询某个特定分类下的文章
查询语句中可能会用到以下几个参数:cat, category__name, category__and, category__and, category__in, category__not_in。例子如下:
查询某个分类下的文章(包含它的子分类)
$query = new WP_Query( 'cat=4' ); // 按分类ID
$query = new WP_Query( 'category_name=staff' ); // 按slug
查询某个分类下的文章(不包含它的子分类)
$query = new WP_Query( 'category__in=4' );
类似的,查询多个分类下的文章
$query = new WP_Query( 'cat=2,6,17,38' ); // ID
$query = new WP_Query( 'category_name=staff,news' ); // slug
不包含某个分类
$query = new WP_Query( 'cat=-12,-34,-56' );
查询同时属于多个分类的文章
如下语句,查询同时包含在ID为2和6两个分类的文章。(注意区分: category__in是“或”的关系,cateory__and是“并”的关系。
$query = new WP_Query( array( 'category__and' => array( 2, 6 ) ) ); // 2 and 6
$query = new WP_Query( array( 'category__in' => array( 2, 6 ) ) ); // 2 or 6
同样的,下面的语句就不难理解了。不包含ID为2或6的分类的文章。
$query = new WP_Query( array( 'category__not_in' => array( 2, 6 ) ) );
通过标签查询
可通过标签查询的条件包括:tag, tag_id, tag__and, tag__in, tag__not_in, tag_slug__and, tag_slug__in。
对应到上面分类的查询方法,不难理解每个条件如何使用,我不一一举例了。(注意:名字中没有slug的,用tag的id查询)。
Taxonomy
Taxonomy是一种的通用的分类。Tag和Category其实都可以算在Taxonomy中,实际上Tag和Category也是利用Taxonomy来实现的,你也可以创建自己的一套Taxonomy,有兴趣的话我们可以在以后的文章中继续讨论Taxonomy。利用Taxonomy,你可以够造适合你需求的各种查询函数。这里我们只拿一个较为复杂的例子来说明:
$args = array(
'post_type' => 'post',
'tax_query' => array(
'relation' => 'OR',
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => array( 'quotes' )
),
array(
'taxonomy' => 'post_format',
'field' => 'slug',
'terms' => array( 'post-format-quote' )
)
)
);
$query = new WP_Query( $args );
本例为查询“在quotes(分类的slug)分类”下或“post_format”为“post-format-quote”的文章('post_type' => 'post')。
搜索
WP_Query也提供了一个简单的基于文关键词的搜索功能,参考下面的例子:
$query = new WP_Query( 's=keyword' );
不过,Wordpress只是单单的对字符串进行匹配,不要指望它会有搜索引擎一样的搜索结果。
总结
WP_Query类包含的内容非常的多,这里也只是介绍了其中的一小部分,有兴趣的读者可以到上面了解更多内容:Class Reference/WP Query。
最后,感谢每一位能坚持把这篇文章读完的人。^_^