基于自定义字段的自定义循环/查询

Avatar of Chris Coyier
Chris Coyier
最后更新者 Jason Witt

如果您设计或开发WordPress主题或插件,则很有可能在某一天需要对自定义元字段进行查询。这些是您可以附加到任何帖子、页面或自定义帖子类型的完全自定义的键值对。WordPress默认情况下具有基本的UI,或者您可以使用诸如Advanced Custom Fields之类的工具来对其进行高级设置。但在后台,ACF使用的是普通的自定义字段。

您现在正在查看的这个代码片段页面是在1999年编写的。当时,为了查询具有特定自定义字段的帖子,您需要使用`$wpdb`全局变量。它可用于创建WordPress WP_Query()类不支持的MySQL查询。幸运的是,如今WordPress确实提供了一些支持自定义元字段查询的参数。

在这里,我们将介绍您可以请求和循环遍历具有特定自定义字段(及其值)的帖子的不同方法。无论您使用WP_Query类、query_posts()还是get_posts(),您都可以使用此信息。由于query_posts()get_posts()WP_Query类的包装器。它们都接受相同的参数。

查询参数

这是一个来自WordPress Codex的WordPress查询基本示例。

<?php
// The Query
$the_query = new WP_Query( $args );

// The Loop
if ( $the_query->have_posts() ) {
  echo '<ul>';
  while ( $the_query->have_posts() ) {
    $the_query->the_post();
    echo '<li>' . get_the_title() . '</li>';
  }
  echo '</ul>';
} else {
  // no posts found
}
/* Restore original Post Data */
wp_reset_postdata();

$args是那里重要的部分。我们将传递不同的参数以使其按我们想要的方式工作。

在查询自定义元数据时,您可以使用两组参数。一组用于简单的自定义元字段查询,另一组用于更复杂的自定义元字段查询。让我们从简单的组开始。

meta_key

meta_key参数将查询任何已将自定义字段元ID保存到数据库的帖子,无论该字段是否保存了值。meta_key是您为元字段指定的ID。像这样

此示例将查询任何具有ID为“field1”的自定义元字段的帖子。

$args = array( 'meta_key' => 'field1' );

meta_value

meta_value参数查询具有您定义的值的帖子。meta_value参数用于字符串值。此示例将查询任何自定义元字段值为“data1”的帖子。

$args = array( 'meta_value' => 'data1' );

您还可以将两者结合起来。此示例将仅查询具有ID为“field1”且值为“data1”的自定义元字段的帖子。

$args = array(
  'meta_key'   => 'field1', 
  'meta_value' => 'data1'
);

meta_value_num

meta_value_num参数类似于meta_value参数。meta_value参数用于字符串值,而meta_value_num参数用于数值值。

此示例演示了如何在“field1”自定义元字段的值为“10”时对其进行查询。

$args = array(
  'meta_key'       => 'field1', 
  'meta_value_num' => '10',
);

meta_compare

meta_compare参数的功能与其名称完全一致。它允许您将比较运算符与meta_valuemeta_value_num参数一起使用。您可以使用的比较运算符为‘=’,‘!=’,‘>’,‘>=’,‘<',‘<=’,‘LIKE’,‘NOT LIKE’,‘IN’,‘NOT IN’,‘BETWEEN’,‘NOT BETWEEN’,‘NOT EXISTS’,‘REGEXP’,‘NOT REGEXP’或‘RLIKE’。以下示例演示了如何查询任何不具有“data1”值的帖子。

$args = array(
  'meta_key'    => 'field1', 
  'meta_value'  => 'data1',
  'meta_compare' => '!=',
);

更复杂的查询

meta_query

用于复杂查询的主要参数是meta_query。此参数本身不执行任何操作。它只是告诉WordPress您要对自定义元字段进行查询。您将在meta_query中添加其他参数,这些参数将用于定义查询。

key、value和compare

参数keyvalue的工作方式与上面描述的meta-keymeta-value完全相同。复杂的compare类似于上面的简单compare,但它采用不同的比较运算符列表。复杂的compare使用‘=’,‘!=’,‘>’,‘>=’,‘<',‘<=’,‘LIKE’,‘NOT LIKE’,‘IN’,‘NOT IN’,‘BETWEEN’,‘NOT BETWEEN’,‘EXISTS’或‘NOT EXISTS’。value可以是数组,但仅当compare使用‘IN’,‘NOT IN’,‘BETWEEN’或‘NOT BETWEEN’时。

如果您将compare与‘EXISTS’或‘NOT EXISTS’一起使用,则无需指定value参数。

以下示例将查询帖子,前提是它具有值为“data1”的“field1”和值为非“data2”的“field2”。

$args = array(
  'meta_query' => array(
    array(
      'key'   => 'field1',
      'value' => 'data1'
    ),
    array(
      'key'     => 'field2',
      'value'   => 'data2',
      'compare' => '!=',
    )
  ) 

);

relation

当您要使用逻辑关系查询自定义元数据时,使用relation。您可以使用ANDOR。例如,您将使用AND来比较data1和data2是否满足条件,并且如果data1或data2满足条件,则使用OR

此参数是独立的。这意味着它不会出现在单个自定义元字段参数中。让我们看一个例子。此示例将仅查询具有值为“data1”的“field1”和值为“data2”的“field2”的帖子。

$args = array(
  'meta_query' => array(
    'relation' => 'AND'
    array(
      'key'   => 'field1', 
      'value' => 'data1',
    ),
    array(
      'key'   => 'field2', 
      'value' => 'data2',
    ),
  )
);

如果您将relation更改为“OR”。然后它将查询任何帖子,前提是“field1”的值为“data1”,或者“field2”的值为“data2”。

type

type参数允许您选择要查询的数据类型。您可以使用‘NUMERIC’,‘BINARY’,‘CHAR’,‘DATE’,‘DATETIME’,‘DECIMAL’,‘SIGNED’,‘TIME’或‘UNSIGNED’。

仅当日期格式为“YYYYMMDD”时,才能将“DATE”类型与compare“BETWEEN”一起使用。

此示例将查询任何“field1”的值为数值的帖子。

$args = array(
  'meta_query' => array(
    array(
      'key'   => 'field1', 
      'value' => 'data1',
      'type' => 'NUMERIC'
    )
  )
);

真实世界示例

到目前为止,我仅提供了使用任意数据和字段的示例。现在,我想向您展示一个查询自定义元字段的真实世界示例。

场景

您创建了一个事件自定义帖子类型。事件帖子类型具有一个日期自定义字段,其 ID 为 event_date。您希望创建一个查询,显示将在当前日期到未来 30 天内开始的任何事件。

我们将使用 meta_query 参数,因为我们希望使用 type 参数将“event_date”字段定义为“DATE”数据类型。

这是查询

$args = array(
  'post_type'      => 'post',
  'posts_per_page' => -1,
  'post_status'    => 'publish',
  'meta_query'     => array(
    array(
      'key'     => 'event_date',
      'value'   => array( date( 'Ymd', strtotime( '-1 day' ) ), date( 'Ymd', strtotime( '+31 days' ) ) ),
      'compare' => 'BETWEEN',
      'type'    => 'DATE'
    ) 
  )
);
$event_query = new WP_Query( $args );

value 是当前日期减 1 天和当前日期加 31 天的数组。由于我们使用的是比较器“BETWEEN”,因此只会查询 value 数组之间的帖子,因此我们希望将它们偏移一天。

使用此查询,您将显示未来 30 天内发生的任何事件。

结论

WP_Query 类是一个非常灵活的类,它允许您创建大量自定义查询。如果您想了解有关查询可以使用的不同参数的更多信息,我建议您查看WP_Query 手册页面