WP_Query 类是 WordPress 文章查询的核心,它的文章查询部分提供了很多可用参数,经过好几个版本的升级完善,让它越来越强大,本文就可以让你详细的了解所有查询参数和技巧。

作者

查询和某些作者 (用户) 有关的文章,可以使用 4 个参数:

  • author(整数):用户 ID
  • author_name(字符串):用户的昵称 (「user_nicename」 字段)
  • author__in(数组):用户 ID
  • author__not_in(数组):用户 ID

获取一个作者的文章

根据用户 ID 获取:

1

$query=newWP_Query('author=123');

根据用户的昵称 (「user_nicename」 字段) 获取:

1

$query=newWP_Query('author_name=rami');

获取多个作者的文章

根据用户 ID 获取多个作者的文章:

1

$query=newWP_Query('author=2,6,17,38');

排除作者的文章

排除一个作者可以使用用户 ID 前边加上 「-」 的方式:

1

$query=newWP_Query('author=-12');

多作者查询

获取多个作者的文章:

1

$query=newWP_Query(array('author__in'=>array(2,6)));

排除多个作者的文章:

1

$query=newWP_Query(array('author__not_in'=>array(2,6)));

分类

关于分类有 5 个可用的参数:

  • cat(整数):分类 ID
  • category_name(字符串):分类别名
  • category__and(数组):分类 ID
  • category__in(数组):分类 ID
  • category__not_in(数组):分类 ID

获取一个分类的文章

根据分类的 ID 获取一个分类的文章 (包含此分类的子分类):

1

$query=newWP_Query('cat=4');

根据分类的别名获取一个分类的文章 (包含此分类的子分类):

1

$query=newWP_Query('category_name=staff');

根据分类的 ID 获取一个分类的文章 (不包含此分类的子分类):

1

$query=newWP_Query('category__in=4');

获取多个分类的文章

根据分类的 ID 获取多个分类的文章:

1

$query=newWP_Query('cat=2,6,17,38');

根据分类别名获取多个分类的文章:

1

$query=newWP_Query('category_name=staff,news');

根据分类别名获取同时拥有几个分类的文章:

1

$query=newWP_Query('category_name=staff+news');

排除分类

想要排除一些分类只需要在分类 ID 前加上 「-」 号:

1

$query=newWP_Query('cat=-12,-34,-56');

多分类查询

获取同时有多个分类的文章,下边的代码会获取必须同时拥有 ID 为 2 和 6 的分类的文章:

1

$query=newWP_Query(array('category__and'=>array(2,6)));

获取多个分类的文章,不包含其子分类,下边的代码获取了拥有 ID 为 2 或者 ID 为 6 的分类的文章:

1

$query=newWP_Query(array('category__in'=>array(2,6)));

排除一些分类的文章:

1

$query=newWP_Query(array('category__not_in'=>array(2,6)));

标签

获取关于标签的文章,可以使用 7 个参数:

  • tag(字符串):标签别名
  • tag_id(整数):标签 ID
  • tag__end(数组):一些标签 ID
  • tag__in(数组):一些标签 ID
  • tag_slug__and(数组):一些标签别名
  • tag_slug__in(数组):一些标签别名

获取一个标签的文章

根据标签别名获取有这个标签的文章:

1

$query=newWP_Query('tag=cooking');

根据标签 ID 获取有这个标签的文章:

1

$query=newWP_Query('tag_id=13');

获取多个标签的文章

根据标签的别名获取带有这几个标签其中一个的文章:

1

$query=newWP_Query('tag=bread,baking');

根据标签别名获取同时拥有几个标签的文章:

1

$query=newWP_Query('tag=bread+baking+recipe');

多标签查询

根据标签 ID 获取同时有几个标签的文章:

1

$query=newWP_Query(array('tag__and'=>array(37,47)));

根据标签 ID 获取有这个标签的文章:

1

$query=newWP_Query(array('tag__in'=>array(37,47)));

根据标签 ID 排除包含某些标签的文章:

1

$query=newWP_Query(array('tag__not_in'=>array(37,47)));

tag_slug__in 和 tag_slug__and 的使用方法同上,只是把 ID 换成别名。

自定义分类法

有关自定义分类法 (Taxonomy) 的查询可以使用 1 个参数:

  • tax_query(数组):分类法查询参数
    • relation(字符串):条件的逻辑关系,OR(或者) 或 AND(和)
    • taxonomy(字符串):分类法名称
    • field(字符串):根据分类法条款的什么字段查询,可选 term_id(分类条款 ID) 、 name(名称) 和 slug(别名),默认是 term_id
    • terms(整数 | 字符串 | 分类):分类法条款
    • include_children(布尔):是否包含子分类法条款,默认是 True
    • operator(字符串):匹配运算符 (IN 、 IN NOT 和 AND),默认是 IN

简单的分类法查询

获取 people 分类法里别名为 bob 的条款下的文章:

$args=array(

    'post_type'=>'post',

    'tax_query'=>array(

        array(

            'taxonomy'=>'people',

            'field'    =>'slug',

            'terms'    =>'bob',

        ),

    ),

);

$query=newWP_Query($args);

多分类法查询

获取同时是 movie_genre 分类法下别名为 action 或 comedy 的条款的文章和不是 actor 分类法下 ID 为 103 或 115 或 206 的条款的文章 (略拗口):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

$args=array(

    'post_type'=>'post',

    'tax_query'=>array(

        'relation'=>'AND',

        array(

            'taxonomy'=>'movie_genre',

            'field'    =>'slug',

            'terms'    =>array('action','comedy'),

        ),

        array(

            'taxonomy'=>'actor',

            'field'    =>'id',

            'terms'    =>array(103,115,206),

            'operator'=>'NOT IN',

        ),

    ),

);

$query=newWP_Query($args);

获取是分类法 category(也就是分类) 下别名为 quotes 的条款或是分类法 post_format 下别名为 post-format-quote 的条款的文章:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

$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=newWP_Query($args);

搜索

显示搜索关键词的结果,只有一个参数。

搜索关键词

搜索一个关键词:

1

$query=newWP_Query('s=keyword');

文章和页面

根据文章信息获取文章。请记住,默认情况下,post_type 一般都是 post(文章) 。 有 9 个参数可以使用:

  • p(整数):文章 ID
  • name(字符串):文章别名
  • page_id(整数):页面 ID
  • postname(字符串):页面别名
  • post_parent(整数):如果填写 ID 则只返回它的子项目,如果填 0 则只返回顶级项目
  • post_parent__in(数组):一些父级项目的 ID,获取它们的子项目
  • post_parent__not_in(数组):一些父级项目的 ID,排除它们的子项目
  • post__in(数组):一些文章 ID
  • post__not_in(数组):一些文章 ID

根据 ID 获取文章或页面

根据 ID 获取文章:

1

$query=newWP_Query('p=7');

根据 ID 获取页面:

1

$query=newWP_Query('page_id=7');

根据别名获取文章或页面

根据别名获取文章:

1

$query=newWP_Query('name=about-my-life');

根据别名获取页面:

1

$query=newWP_Query('pagename=contact');

获取文章或页面的子项目

根据别名获取一个页面的子页面,contact_us 是父页面别名,canada 是子页面别名:

1

$query=newWP_Query('pagename=contact_us/canada');

获取一个文章的子项目:

1

$query=newWP_Query('post_parent=93');

获取所有顶级项目:

1

$query=newWP_Query('post_parent=0');

同时获取多个父级文章的子项目:

1

$query=newWP_Query(array('post_parent__in'=>array(2,5,12,14,20)));

多文章和页面查询

根据 ID 获取几个页面:

1

$query=newWP_Query(array('post_type'=>'page','post__in'=>array(2,5,12,14,20)));

排除几个 ID 的文章:

1

$query=newWP_Query(array('post_type'=>'post','post__not_in'=>array(2,5,12,14,20)));

PS:post__in 和 post__not_in 不能一起用。 PS2:post__not_in 不能使用以逗号分隔的字符串,只能是数组:

//这是错误的,不会工作

$query=newWP_Query('post__not_in=1,2,3');

//这才是正确的

$query=newWP_Query(array('post__not_in'=>array(1,2,3)));

密码

有关文章密码的查询,可以使用 2 个参数:

  • has_password(布尔):文章是否有密码
  • post_password(字符串):指定的文章密码

有无密码

获取有密码的文章:

1

$query=newWP_Query(array('has_password'=>true));

获取没有密码的文章:

1

$query=newWP_Query(array('has_password'=>false));

指定密码

获取密码是指定内容的文章:

1

$query=newWP_Query('post_password=123');

类型

有关文章类型的查询,只有一个参数可以使用:

  • post_type(字符串 | 数组):文章的类型,一般默认都是 post(文章)

一个文章类型

获取页面:

1

$query=newWP_Query('post_type=page');

获取自定义文章类型:

1

$query=newWP_Query('post_type=custom_post_type_name');

多个文章类型

获取多个文章类型:

1

$query=newWP_Query(array('post_type'=>array('post','page','movie','book')));

获取全部文章类型:

1

$query=newWP_Query('post_type=any');

状态

有关文章状态的查询。文章状态指的是文章当前处于什么情况,比如 「已发布」 、 「草稿」 、 「待审核」 和 「定时发布」 等等,文章状态是可以由主题或者插件开发者扩展的。 关于文章状态可以使用一个参数:

  • post_status(字符串 | 数组):文章的状态,一般默认都是 publish(已发布)

获取一个状态的文章

获取草稿文章:

1

$query=newWP_Query('post_status=draft');

获取多个状态的文章

获取多个状态下的文章:

1

$query=newWP_Query(array('post_status'=>array('pending','draft','future')));

获取全部状态的文章:

1

$query=newWP_Query('post_status=any');

分页

有关分页的查询,有 7 个参数可以使用:

  • nopaging(布尔):将文章分页还是全部获取。默认是 False:分页
  • posts_per_page(整数):每页显示多少文章,如果设置成 –1 则不分页
  • posts_per_archive_page(整数):和 posts_per_page 是一样的,不过这个只有在当前查询是根据存档或是搜索的情况下才生效
  • offset(整数):偏移值,去掉前边几篇文章,再从后边找回来
  • paged(整数):页码,指定文章分页的当前页
  • page(整数):静态首页的页码
  • ignore_sticky_posts(布尔):是否忽略指定文章,要忽略置顶文章可以设置成 True,默认是 False

设置每页文章数

设置每页的文章数量为 3 篇文章:

1

$query=newWP_Query('posts_per_page=3');

显示全部文章

获取全部文章,不分页 (方法一):

1

$query=newWP_Query('nopagi

ng=1');

获取全部文章,不分页 (方法二):

1

$query=newWP_Query('posts_per_page=-1');

偏移

从第 4 个文章开始获取:

1

$query=newWP_Query('offset=3'));

每页 5 篇文章,而但向前移位 3 篇:

1

$query=newWP_Query(array('posts_per_page'=>5,'offset'=>3));

获取第 N 页文章

获取第 6 页的文章:

1

$query=newWP_Query('paged=6');

获取当前页文章

获取当前页文章:

1

$query=newWP_Query(array('paged'=>get_query_var('paged')));

获取当前页文章,如果没有指定页码则默认第一页:

$paged=(get_query_var('paged'))?get_query_var('paged'):1;

$query=newWP_Query(array('paged'=>$paged));

置顶文章

获取第一篇置顶文章:

$sticky=get_option('sticky_posts');

$query=newWP_Query('p='.$sticky[0]);

获取第一篇置顶文章,如果没有置顶文章则获取一篇最新的文章:

$args=array(

    'posts_per_page'      =>1,

    'post__in'            =>get_option('sticky_posts'),

    'ignore_sticky_posts'=>1,

);

$query=newWP_Query($args);

排除置顶文章

排除全部置顶文章:

1

$query=newWP_Query(array('post__not_in'=>get_option('sticky_posts')));

忽略指定文章的置顶性,在循环里按正常排序出现:

1

$query=newWP_Query('ignore_sticky_posts=1');

排序和排序类型

有关文章排序方法和类型的查询,有两个参数可以使用:

  • order(字符串 | 数组):排序方法,ASC 为正序 (从小到大);DESC 为倒序 (从大到小)
  • orderby(字符串 | 数组):根据什么字段排序,默认是 post_date(文章日期)

按标题倒序

根据文章标题进行倒序排列:

1

$query=newWP_Query(array('orderby'=>'title','order'=>'DESC'));

先根据 menu_order 排序,如果出现无法排序的情况 (比如相同或者为空) 则再利用 title 排序。

1

$query=newWP_Query(array('orderby'=>'menu_order title','order'=>'DESC'));

随机排序

获取一篇随机文章:

1

$query=newWP_Query(array('orderby'=>'rand','posts_per_page'=>'1'));

热门文章

获取根据评论数量排序的文章:

1

$query=newWP_Query(array('orderby'=>'comment_count'));

多条件不同排序

给多个排序条件,每个排序条件有不同的排序方法:

1

$query=newWP_Query(array('orderby'=>array('title'=>'DESC','menu_order'=>'ASC')));

自定义字段

获取文章自定义字段 age 是 3 或 4 的文章,并且按照 age 字段值的数字大小排序:

$args=array(

    'meta_key'   =>'age',

    'orderby'    =>'meta_value_num',

    'order'      =>'ASC',

    'meta_query'=>array(

        array(

            'key'     =>'age',

            'value'   =>array(3,4),

            'compare'=>'IN',

        ),

    ),

);

$query=newWP_Query($args);

日期

和文章日期有关的查询,有 9 个参数:

  • year(整数):4 位数的年份,比如 2014
  • monthnum(整数):月份,从 1 到 12
  • w(整数):周,从 0 到 53
  • day(整数):日,从 1 到 31
  • hour(整数):小时,从 0 到 23
  • minute(整数):分钟,从 0 到 60
  • second(整数):秒,从 0 到 60
  • m(整数):年月,比如 201409
  • date_query(数组):复杂的日期查询
    • year(整数):4 位数的年份,比如 2014
    • month(整数):月份,从 1 到 12
    • week(整数):周,从 0 到 53
    • day(整数):日,从 1 到 31
    • hour(整数):小时,从 0 到 23
    • minute(整数):分钟,从 0 到 59
    • second(整数):秒,从 0 到 59
    • before(字符串 | 数组):开启查询日期,可以是能被 strtotime() 函数解析的日期字符串,还可以使用数组:
      • year(整数):4 位数的年份,比如 2014,默认为空
      • month(整数):月份,从 1 到 12,默认是 1
      • day(整数):日,从 1 到 31,默认是 1
    • after(字符串 | 数组):结束查询日期,可以是能被 strtotime() 函数解析的日期字符串,还可以使用数组:
      • year(整数):4 位数的年份,比如 2014,默认为空
      • month(整数):月份,从 1 到 12,默认是 12
      • day(整数):日,从 1 到 31,默认是本月最后一天
    • inclusive(布尔):before 和 after 是否包含所指定本日的文章
    • compare(字符串):使用什么比较符号 (=、!=、> 、>=、< 、<=、 IN 、 NOT IN 、 BETWEEN 、 NOT 、 BETWEEN)
    • column(字符串):匹配的日期字段,默认是 post_date
    • relation(字符串):条件的逻辑关系,OR(或者) 或 AND(和)

获取 2012 年 12 月 12 日的文章

1

$query=newWP_Query('year=2012&monthnum=12&day=12');

或者:

$args=array(

    'date_query'=>array(

        array(

            'year'  =>2012,

            'month'=>12,

            'day'   =>12,

        ),

    ),

);

$query=newWP_Query($args);

获取今天发布的文章

$today=getdate();

$query=newWP_Query('year='.$today['year'].'&monthnum='.$today['mon'].'&day='.$today['mday']);

或者:

$today=getdate();

$args=array(

    'date_query'=>array(

        array(

            'year'  =>$today['year'],

            'month'=>$today['mon'],

            'day'   =>$today['mday'],

        ),

    ),

);

$query=newWP_Query($args);

获取本周发布的文章

$week=date('W');

$year=date('Y');

$query=newWP_Query('year='.$year.'&w='.$week);

或者:

$args=array(

    'date_query'=>array(

        array(

            'year'=>date('Y'),

            'week'=>date('W'),

        ),

    ),

);

$query=newWP_Query($args);

获取上午 9 点到下午 5 点的文章

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

$args=array(

    'date_query'=>array(

        array(

            'hour'      =>9,

            'compare'   =>'>=',

        ),

        array(

            'hour'      =>17,

            'compare'   =>'<=',

        ),

        array(

            'dayofweek'=>array(2,6),

            'compare'   =>'BETWEEN',

        ),

    ),

    'posts_per_page'=>-1,

);

$query=newWP_Query($args);

获取 2013 年 1 月 1 日到 2013 年 2 月 18 日的文章

包含 2013 年 1 月 1 日和 2013 年 2 月 18 日的文章:

$args=array(

    'date_query'=>array(

        array(

            'after'     =>'January 1st, 2013',

            'before'    =>array(

                'year'  =>2013,

                'month'=>2,

                'day'   =>28,

            ),

            'inclusive'=>true,

        ),

    ),

    'posts_per_page'=>-1,

);

$query=newWP_Query($args);

不包含 2013 年 1 月 1 日和 2013 年 2 月 18 日的文章:

$args=array(

    'date_query'=>array(

        array(

            'after'     =>'January 1st, 2013',

            'before'    =>array(

                'year'  =>2013,

                'month'=>2,

                'day'   =>28,

            ),

            'inclusive'=>false,

        ),

    ),

    'posts_per_page'=>-1,

);

$query=newWP_Query($args);

获取在一年前发布却在一个月前修改过的文章

$args=array(

    'date_query'=>array(

        array(

            'column'=>'post_date_gmt',

            'before'=>'1 year ago',

        ),

        array(

            'column'=>'post_modified_gmt',

            'after'  =>'1 month ago',

        ),

    ),

    'posts_per_page'=>-1,

);

$query=newWP_Query($args);

自定义字段

有关自定义字段的查询,可用使用 9 个参数:

  • meta_key(字符串):自定义字段的名 (key)
  • meta_value(字符串):自定义字段的值 (value)
  • meta_value_num(数字):自定义字段的值 (value)
  • meta_compare(字符串):匹配方法 (=、!=、> 、>=、< 、<=),默认是 「=」
  • meta_query(数组):处理复杂的查询
    • relation(字符串):条件的逻辑关系,OR(或者) 或 AND(和)
    • key(字符串):自定义字段的名 (key)
    • value(字符串):自定义字段的值 (value)
    • compare(字符串):匹配方法 (=、!=、> 、>=、< 、<=、 LIKE 、 NOT LIKE 、 IN 、 NOT IN 、 BETWEEN 、 NOT BETWEEN 、 EXISTS 、 NOT EXISTS),默认是 「=」
    • type(字符串):自定义字段的类型 (NUMERIC 、 BINARY 、 CHAR 、 DATE 、 DATETIME 、 DECIMAL 、 SIGNED 、 TIME 、 UNSIGNED),默认是 「CHAR」

简单的自定义字段查询

获取拥有自定义字段 color 的文章:

1

$query=newWP_Query('meta_key=color');

获取自定义字段的值为 「blue」 的文章,不管字段的键值是什么:

1

$query=newWP_Query('meta_value=blue');

获取自定义字段的值为 「blue」 的页面,不管字段的键值是什么:

1

$query=newWP_Query('meta_value=blue&post_type=page');

获取自定义字段 color 是 「blue」 的文章:

1

$query=newWP_Query(array('meta_key'=>'color','meta_value'=>'blue'));

获取自定义字段 color 不是 「blue」 的文章:

1

$query=newWP_Query(array('meta_key'=>'color','meta_value'=>'blue','meta_compare'=>'!='));

获取文章类型是 「product」 的文章,并且自定义字段 price 小于或者等于 22:

1

$query=newWP_Query(array('meta_key'=>'price','meta_value'=>'22','meta_compare'=>'<=','post_type'=>'product'));

简单的复杂查询

获取 product 自定义文章类型中 color 自定义字段不包含 「blue」 的文章:

$args=array(

    'post_type'  =>'product',

    'meta_query'=>array(

        array(

            'key'     =>'color',

            'value'   =>'blue',

            'compare'=>'NOT LIKE',

        ),

    ),

);

$query=newWP_Query($args);

复杂的查询

多自定义字段匹配:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

$args=array(

    'post_type'  =>'product',

    'meta_query'=>array(

        array(

            'key'     =>'color',

            'value'   =>'blue',

            'compare'=>'NOT LIKE',

        ),

        array(

            'key'=>'price',

            'value'   =>array(20,100),

            'type'    =>'numeric',

            'compare'=>'BETWEEN',

        ),

    ),

);

$query=newWP_Query($args);

在 product 自定义文章类型里获取 color 自定义字段不包含 「blue」 或者 price 字段是 20 到 100 之间的文章:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

$args=array(

    'post_type'  =>'product',

    'meta_query'=>array(

        'relation'=>'OR',

        array(

            'key'     =>'color',

            'value'   =>'blue',

            'compare'=>'NOT LIKE',

        ),

        array(

            'key'     =>'price',

            'value'   =>array(20,100),

            'type'    =>'numeric',

            'compare'=>'BETWEEN',

        ),

    ),

);

$query=newWP_Query($args);

用户权限

关于用户权限的文章查询有一个参数可以使用:

只有用户有权限才显示文章

只有用户有权限才获取已发布和私密的文章:

1

$query=newWP_Query(array('post_status'=>array('publish','private'),'perm'=>'readable'));

文章缓存

有关文章数据的缓存,有 3 个参数:

  • cache_results(布尔):文章信息缓存
  • update_post_meta_cache(布尔):文章 meta 信息缓存
  • update_post_term_cache(布尔):文章分类法信息缓存

获取文章但不更新文章缓存

1

$query=newWP_Query(array('posts_per_page'=>50,'cache_results'=>false));

获取文章但不更新 meta 信息的缓存

1

$query=newWP_Query(array('posts_per_page'=>50,'update_post_meta_cache'=>false));

获取文章但不更新文章分类法的缓存

1

$query=newWP_Query(array('posts_per_page'=>50,'update_post_term_cache'=>false));

其它

由于本文内容太多,耗时好几天才完成制作,如果出现不准确的内容请在评论中指出,谢谢!

更多关于文章查询的内容:https://www.weixiaoduo.com/tag/query

参考资料:https://codex.WordPress.org/Class_Reference/WP_Query