You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WordPress RestAPI自定义文章类型重复字段注册异常问题

解决WordPress REST API自定义文章类型重复字段返回null的问题

问题描述

注册自定义文章类型reservations后,普通字段可正常通过API返回,但重复字段occupants出现异常:初始代码中该字段未出现在API的meta结果里;将register_post_meta的第一个参数改为reservations后,字段显示但值为null(实际已录入有效数据)。

问题根源

  1. 初始版本问题:使用register_post_meta('post', ...)并添加object_subtype,但数组类型元数据需要明确的REST Schema定义,WordPress未正确识别该字段的结构,导致字段不显示。
  2. 修改后版本问题:Schema中错误地将items的type设为string,但每个occupant是包含多个属性的对象,API无法解析存储的序列化数据,因此返回null。
  3. 缺少必要的sanitize_callback和auth_callback,且未设置默认值,进一步加剧了解析异常。

解决方案

修正元数据注册代码,调整Schema结构并补充必要的回调函数:

add_action( 'init', 'booking_register_meta' );
function booking_register_meta(){
    // 注册自定义文章类型
    register_post_type(
        'reservations',
        array(
            'labels' => array(
                'name' => _( 'Reservations' ),
                'singular_name' => _( 'Reservation' ),
            ),
            'public' => true,
            'has_archive' => true,
            'show_in_rest' => true,
            'supports' => array(
                'title',
                'custom-fields',
                'revisions',
            )
        )
    );

    // 注册普通字段
    register_meta(
        'post',
        'reservation-status',
        array(
            'single'       => true,
            'type'         => 'string',
            'default'      => '',
            'show_in_rest' => true,
            'object_subtype' => 'reservations'
        )
    );

    // 修正后的重复字段注册代码
    register_post_meta(
        'reservations',
        'occupants',
        array(
            'single'       => true, // 存储为单条序列化数组记录
            'type'         => 'array',
            'default'      => array(), // 设置默认空数组避免返回null
            'show_in_rest' => array(
                'schema' => array(
                    'type'  => 'array',
                    'items' => array(
                        'type'       => 'object', // 每个元素是对象而非字符串
                        'properties' => array(
                            'occupant-first-name' => array(
                                'type' => 'string',
                            ),
                            'occupant-last-name' => array(
                                'type' => 'string',
                            ),
                            'occupant-full-name' => array(
                                'type' => 'string',
                            ),
                            'occupant-age' => array(
                                'type' => 'string',
                            ),
                            'occupant-gender' => array(
                                'type' => 'string',
                            ),
                        ),
                    ),
                ),
            ),
            // 清理数据确保格式合规
            'sanitize_callback' => function($value) {
                $sanitized = array();
                foreach ($value as $item) {
                    $sanitized_item = array();
                    foreach ($item as $key => $val) {
                        if (str_starts_with($key, 'occupant-')) {
                            $sanitized_item[$key] = sanitize_text_field($val);
                        }
                    }
                    $sanitized[] = $sanitized_item;
                }
                return $sanitized;
            },
            // 控制字段读写权限
            'auth_callback' => function() {
                return current_user_can('edit_posts');
            },
        )
    );
}

关键修正点

  1. Schema类型修正:将items的type从string改为object,匹配每个occupant的对象结构,让API能正确解析数据。
  2. Single参数设置:设为true,因为重复字段通常存储为单条序列化数组(而非多条独立的元数据记录)。
  3. 补充回调函数:sanitize_callback确保数据格式合规,auth_callback控制字段的读写权限。
  4. 默认值设置:default设为空数组,避免字段无数据时返回null。

额外检查

  • 确认数据库wp_postmeta表中,reservations类型文章的occupants元数据值是序列化的数组(而非多条独立记录)。
  • 如果之前存储的是多条元数据记录,需修改为单条序列化数组,或调整single参数为false并对应修改Schema解析逻辑。

内容的提问来源于stack exchange,提问作者Bunsen Honeydew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 08:55:31