场景:克隆组里的 Radio 子字段
之前我们讲过怎么按 Meta Box Group 的 text/number/Datepicker 子字段筛选 Bricks 文章查询循环,这篇专门讲 Radio(单选)类型的子字段——它是 Meta Box 组字段筛选里最让人困惑的一种,因为单选值存在序列化数据里,没法用普通的等值查询。
场景如下:
- CPT:
store - 字段组:
session(可克隆的 Group 组)session_name(text)session_type(radio),选项:Individual / Duet / Trio
一篇文章可以有一个或多个 session(比如一家店可以开多场活动,每场活动一个 session,每个 session 有名字和类型)。目标是:只显示 session_type 等于指定字符串(如 Individual 或 Duet 或 Trio)的文章——例如“找出所有提供 Duet 双人课程的店”。
难点在于:Meta Box 的 Group 字段在数据库里是序列化(serialized)存储的,子字段并不是独立的自定义字段行,而是打包在一长串 PHP serialize 文本里。因此不能直接按子字段值做等值查询(compare => '='),需要用 LIKE 去匹配序列化串里的子字段片段。
Step 1:PHP 查询与序列化匹配
在页面或模板里设置查询循环,启用 PHP 查询,粘贴:
$session_type = 'Individual';
// 校验会话类型
$valid_types = [ 'Individual', 'Duet', 'Trio' ];
if ( ! in_array( $session_type, $valid_types, true ) ) {
return [ 'post__in' => [ 0 ] ]; // 非法类型返回空结果
}
return [
'post_type' => 'store',
'posts_per_page' => -1,
'no_found_rows' => true,
'meta_query' => [ // 按会话类型筛选
[
'key' => 'session',
'value' => '"session__type";s:' . strlen( $session_type ) . ':"' . $session_type . '"',
'compare' => 'LIKE',
],
]
];
第一行 $session_type 就是要筛选的会话类型,按需改成 Duet 或 Trio。开头那段 in_array 校验是防御性写法:万一传入的值不在合法选项里,直接返回空结果,避免构造出无效的查询条件。签名代码(Sign code)并保存。
序列化匹配原理
中间那句 value 是关键:
"session__type";s:' . strlen( $session_type ) . ':"' . $session_type . '"
它构造出一个匹配 PHP 序列化格式的搜索串。Meta Box 把 Group 数据按 PHP serialize 规则存进数据库,形如:
a:1:{s:7:"session";a:2:{s:11:"session__type";s:10:"Individual";...}}
其中 s:10:"Individual" 里的 10 是字符串长度。我们的 value 用 strlen($session_type) 动态算长度,再拼上 "session__type";s:{长度}:"{值}",正好能精确匹配到 session__type 子字段的值片段,包括字段名、字符串指示符、字符数和值本身,避免误匹配到名字相近的其他字段。配合 compare => LIKE 就能筛出“至少有一个组满足条件”的文章。
两点提醒:一是长度必须动态计算,手写数字一旦值和长度对不上就匹配不到;二是 compare 必须是 LIKE 而不是 =——因为目标是一个长序列化字符串的子串,不是独立字段值。
Step 2:输出文章标题
在启用了查询循环的 Block 里添加一个 Post Title 元素,用于展示筛选结果。
搞定!现在查询循环只会显示至少有一个组的 Radio 子字段值匹配指定类型的文章。这个方法同样适用于其他 Meta Box 可克隆组 + 单选子字段的组合,只要把字段名、选项值和长度计算逻辑照抄改改就行。嵌套更深的多层 Group 结构也能用同样的 LIKE 思路,把要匹配的每一层字段名按序列化顺序拼接进搜索串即可。
如果你用的是 ACF 的 Repeater 组字段,存储结构和 Meta Box 不同(ACF Repeater 每行是独立的自定义字段记录),不能用这个序列化匹配法,需要改用 ACF 的 meta_query 行级查询或 acf/fields/repeater 相关过滤器——两个插件的组字段筛选思路不一样,别混用。
小结:Meta Box 序列化存储决定了这类筛选必须用 LIKE 匹配序列化片段。记住两个易错点:一是 value 里用 strlen() 动态计算长度而不是手写数字,二是 compare 必须是 LIKE 而不是 =。掌握了这个模式,Meta Box 组字段的子字段筛选基本都能套用——无论子字段是 Radio、Select 还是 Checkbox,套路完全一致,只是把要匹配的字段名和值换掉而已。