使用高级自定义字段按自定义字段查询帖子

高级自定义字段 显然是一个很棒的插件,但是它的 API 有一两件事可以变得更容易。

例如,在普通 ACF 中,没有简单的方法可以从字段名称中获取字段对象,尽管 文件说. 这 get_field_object 如果按名称查询,则仅返回部分信息 – 要返回您需要使用字段键的完整对象。 (旁注:在 ACF Pro 中它更容易一些,因为您可以使用 acf_get_field 函数 返回完整的字段对象。)

如果您在自己创建字段的单个已知站点上进行开发,那很好。 但是,如果您正在开发使用 ACF 的主题或插件,您不知道密钥,而找到它们的唯一方法是 相当复杂.

另一个问题是根据自定义字段值选择帖子。

单值字段

基于简单的单值字段(例如“数字”或“文本”)选择帖子非常简单。 您只需使用标准 WP_Meta_Query 字段。 我不会在这里重述这些内容,但您可以阅读文档了解详细信息。

示例查询

假设我们根据两个自定义字段选择帖子 – emailnum_articles. 我们要选择邮件为 [email protected] 且文章数量大于 1 的所有帖子:

$args = array(
  'post_type' => 'post',
  'meta_query' => array(
    'relation' => 'AND',
    array(
      'key' => 'email',
      'value' => '[email protected]',
      'compare' => '='
    ),
    array(
      'key' => 'num_articles',
      'value' => 1,
      'type' => 'NUMERIC',
      'compare' => '>'
    )
  )
);

$posts = get_posts( $args );
// etc...

这一切都很简单,与没有 ACF 的自定义字段查询没有什么不同。

基于数组的字段

但是,当使用基于数组的字段(例如复选框)或允许多选的字段时,它会变得更加复杂。

文档说你应该使用 LIKE 运算符 对于这些领域,乍一看是有道理的。

考虑一个复选框字段(字段名称: checkbox_field)。 具有此字段的帖子将在 wp_post_meta 看起来像:

meta_id post_id 元密钥 元值
1 123 复选框字段 a:2:{i:0;s:3:”一个”;i:1;s:5:”三个”;}

meta_value column 是我们感兴趣的位。由于这是一个基于数组的字段,因此 value 是一个序列化数组。 所以在这种情况下,我们有一个长度为 2 的数组,其中包含两个值: .

示例查询

使用 LIKE 运算符根据此字段选择帖子可能如下所示:

$args = array(
  'post_type' => 'post',
  'meta_query' => array(
    array(
      'key' => 'checkbox_field',
      'value' => 'three',
      'compare' => 'LIKE'
    )
  )
);

$posts = get_posts( $args );
// etc...

在这种情况下,一切正常。

另一个例子

但是,考虑一个允许多部分的用户字段:

包含此字段的帖子将有一个 user_field 价值在 wp_post_meta 看起来像:

meta_id post_id 元密钥 元值
2 123 用户字段 a:1:{i:0;s:1:”2″;}
3 125 用户字段 a:2:{i:0;s:1:”3″;i:1;s:2:”11″}
4 127 用户字段 a:1:{i:0;s:1:”4″;}

因此,在这种情况下,这些值存储为包含用户 ID 的数组。

意想不到的结果

使用此字段的查询可能如下所示:

$args = array(
  'post_type' => 'post',
  'meta_query' => array(
    array(
      'key' => 'user_field',
      'value' => '2',
      'compare' => 'LIKE'
    )
  )
);

$posts = get_posts( $args );
// etc...

然而,这会产生意想不到的结果。 由于这些值是序列化数组,因此上述查询将匹配 2 个帖子 – 123 和 125 – 因为两者都包含字符串“2”。 第一个 (post_id = 123) 是正确的,因为“2”指的是我们正在寻找的用户 ID。 但是第二个结果是获取序列化的字符串引用“s:2”,我们绝对不希望在结果中出现这种情况。

改进查询

一种基于数组值选择帖子的改进方法需要考虑到这一点。 这 WP_Meta_Query 的文档 提到(从 3.7 开始)它支持 SQL 运算符,例如“REGEXP”和“NOT REGEXP”。 这可以用来改进上面示例中的字段选择,生成如下所示的内容:

$args = array(
  'post_type' => 'post',
  'meta_query' => array(
    array(
      'key' => 'user_field',
      'value' => '^2$|s:1:"2";',
      'compare' => 'REGEXP'
    )
  )
);

$posts = get_posts( $args );
// etc...

现在将返回正确数量的帖子,因为它考虑了序列化格式。 如果字段存储为单个值(例如,如果您将字段从多选切换到单选),我们还有一个替代选项。

要从变量字段值自动生成此查询,您可以使用以下代码:

$search_value="xyz"; // whatever
$field_value = sprintf( '^%1$s$|s:%2$u:"%1$s";', $search_value, strlen( $search_value ) );

$args = array(
  'post_type' => 'post',
  'meta_query' => array(
    array(
      'key' => 'user_field',
      'value' => $field_value,
      'compare' => 'REGEXP'
    )
  )
);
// etc...

您显然可以将其与其他元查询结合使用,以基于多个字段选择帖子 AND 或者 OR 运营商。

  WooCommerce 隐藏价格:4 种无需代码的简单方法

结论

目前,这是我所知道的在基于数组的字段中搜索的最佳方法。 WP 或 ACF 中没有本地方式,但如果您知道更好的方式,请在下面的评论中分享。 如果您对此有任何其他意见或改进,请告诉我。

类似文章