0

0

使用Opis JSON Schema验证包含特定固定值对象的JSON数组

花韻仙語

花韻仙語

发布时间:2025-12-13 20:38:15

|

482人浏览过

|

来源于php中文网

原创

使用opis json schema验证包含特定固定值对象的json数组

本教程将指导您如何使用Opis JSON Schema库验证一个JSON数组,确保其中至少包含一个具有特定固定整数值(例如`id`为`1`)的关联数组(在JSON中表现为对象)。文章将深入探讨在PHP中处理数据类型转换(将关联数组转换为JSON对象)和精确定义JSON Schema规则(特别是`contains`和`type`关键字)的关键步骤,以解决常见的验证失败问题,并提供完整的代码示例和最佳实践。

在现代Web应用中,数据验证是确保数据完整性和安全性的关键环节。JSON Schema提供了一种强大而灵活的方式来定义JSON数据的结构和约束。当我们需要验证一个JSON数组,并要求该数组中至少包含一个满足特定条件的JSON对象时,Opis JSON Schema库是一个非常实用的工具。本文将详细介绍如何正确地配置数据和Schema,以实现这一复杂的验证逻辑。

理解验证目标

我们的目标是验证一个PHP数组,该数组在转换为JSON后,是一个包含多个对象的数组。我们希望确保这个JSON数组中至少有一个对象,其id属性的值精确为1。例如,对于以下数据:

$json = [
    [
        'id' => 1,
    ],
    [
        'id' => 2,
    ],
    [
        'id' => 3
    ]
];

我们期望验证能够成功,因为第一个对象满足id为1的条件。

初始尝试与常见陷阱

在初次尝试使用Opis JSON Schema进行验证时,开发者可能会遇到一些问题。以下是一个常见的初始Schema定义和数据准备方式:

// 初始数据(PHP关联数组)
$json = [
    ['id' => 1],
    ['id' => 2],
    ['id' => 3]
];

// 初始Schema定义
$rules = [
    'type' => 'array',
    'contains' => [
        'type' => 'array', // 潜在错误:这里应该是 'object'
        'properties' => [
            'id' => [
                'type' => 'integer',
                'const' => 1,
            ],
        ],
        'required' => ['id']
    ],
    'minContains' => 1,
];

使用上述数据和Schema进行验证时,可能会得到类似“At least 1 array items must match schema”的错误信息,即使数据看起来是符合预期的。这通常是由于两个关键问题造成的:

  1. 数据类型不匹配: Opis JSON Schema在处理PHP数组时,默认情况下会将关联数组(如['id' => 1])视为普通的PHP数组,而不是JSON对象(stdClass实例)。JSON Schema的type: object期望的是JSON对象。
  2. Schema定义错误: 在contains关键字中,我们指定了'type' => 'array',但实际上我们期望匹配的是一个JSON对象,而不是另一个数组。

解决方案:数据预处理与Schema修正

为了成功进行验证,我们需要修正上述两个问题。

1. 数据预处理:将PHP关联数组转换为JSON对象

Opis JSON Schema期望PHP中的JSON对象以stdClass实例的形式存在。将PHP关联数组直接传递给验证器,它可能无法正确识别为JSON对象。最可靠的方法是先将PHP数组json_encode成JSON字符串,然后再json_decode回PHP变量。这将确保所有关联数组都被转换为stdClass对象。

Picsart
Picsart

Picsart是全球最大的数字创作平台。

下载
// 原始PHP数组
$dataToValidate = [
    ['id' => 1],
    ['id' => 2],
    ['id' => 3]
];

// 关键的数据预处理步骤:
// 1. json_encode 转换为JSON字符串
// 2. json_decode 转换为PHP对象(stdClass)
$processedData = json_decode(json_encode($dataToValidate));

现在,$processedData中的每个内部数组都已是stdClass的实例,Opis验证器能够正确将其识别为JSON对象。

2. 修正JSON Schema定义

contains关键字用于指定数组中必须至少包含一个满足特定子Schema的元素。我们需要确保这个子Schema的type属性正确地设置为object,因为我们正在寻找的是一个JSON对象。

$correctedRules = [
    'type' => 'array', // 顶层是一个数组
    'contains' => [
        'type' => 'object', // 修正:数组中的元素是对象,不是数组
        'properties' => [
            'id' => [
                'type' => 'integer',
                'const' => 1, // 要求id的值必须是1
            ],
        ],
        'required' => ['id'] // 要求id属性必须存在
    ],
    'minContains' => 1, // 数组中至少要有一个元素匹配'contains'定义的Schema
];

完整的验证示例

结合数据预处理和修正后的Schema,以下是使用Opis JSON Schema进行验证的完整代码示例:

首先,确保你已经通过Composer安装了Opis JSON Schema库:

composer require opis/json-schema

然后,在你的PHP代码中:

validate($json, $rules);

        if ($result->isValid()) {
            return true;
        }

        $errorMessages = [];

        if ($result->hasError()) {
            $formatter = new ErrorFormatter();
            // 格式化错误信息,通常会返回一个数组,每个元素是一个错误详情
            $errorMessages[] = $formatter->format($result->error());
        }

        return $errorMessages;
    }
}

// 原始数据
$dataToValidate = [
    [
        'id' => 1,
    ],
    [
        'id' => 2,
    ],
    [
        'id' => 3
    ]
];

// 关键的数据预处理:将PHP关联数组转换为JSON对象
$processedData = json_decode(json_encode($dataToValidate));

// 修正后的Schema规则
$rules = [
    'type' => 'array',
    'contains' => [
        'type' => 'object', // 修正为 'object'
        'properties' => [
            'id' => [
                'type' => 'integer',
                'const' => 1, // 确保id的值为1
            ],
        ],
        'required' => ['id'] // 确保id属性存在
    ],
    'minContains' => 1, // 确保至少有一个对象满足条件
];

// 执行验证
$validated = Common::validateJSON($processedData, json_encode($rules)); // Opis validator expects schema as string or object

if ($validated === true) {
    echo "验证成功:JSON数组中包含至少一个id为1的对象。\n";
} else {
    echo "验证失败:\n";
    print_r($validated);
}

// 示例2:验证失败的情况 (没有id为1的对象)
echo "\n--- 验证失败示例 ---\n";
$dataToFail = [
    ['id' => 10],
    ['id' => 20],
];
$processedDataFail = json_decode(json_encode($dataToFail));
$validatedFail = Common::validateJSON($processedDataFail, json_encode($rules));

if ($validatedFail === true) {
    echo "验证成功 (不应出现此情况)。\n";
} else {
    echo "验证失败 (符合预期):\n";
    print_r($validatedFail);
}

// 示例3:验证失败的情况 (对象中没有id属性)
echo "\n--- 验证失败示例 (缺少属性) ---\n";
$dataToFailMissingId = [
    ['name' => 'test'],
    ['id' => 2],
];
$processedDataFailMissingId = json_decode(json_encode($dataToFailMissingId));
$validatedFailMissingId = Common::validateJSON($processedDataFailMissingId, json_encode($rules));

if ($validatedFailMissingId === true) {
    echo "验证成功 (不应出现此情况)。\n";
} else {
    echo "验证失败 (符合预期):\n";
    print_r($validatedFailMissingId);
}

运行上述代码,第一个示例将输出“验证成功”,而后两个示例将输出详细的错误信息,表明验证失败,这符合我们的预期。

注意事项与最佳实践

  • 数据类型一致性: 在使用任何JSON Schema验证库时,始终确保你的数据在传入验证器之前,其内部结构(尤其是数组和对象)与JSON Schema的期望相匹配。PHP关联数组默认不会被视为stdClass对象,需要显式转换。
  • Schema的type关键字: type关键字是JSON Schema中最基础也是最重要的部分。仔细检查每个层次的type定义,确保它们与你数据的实际结构相符。
  • contains与minContains: contains定义了数组中至少一个元素必须满足的Schema,而minContains则指定了满足该Schema的元素的最少数量。它们通常一起使用。
  • 错误处理: Opis JSON Schema提供了详细的错误信息。利用ErrorFormatter可以帮助你更好地理解验证失败的原因,这对于调试Schema定义至关重要。
  • Schema可读性: 对于复杂的Schema,使用注释或将其拆分为更小的、可复用的部分可以提高可读性和维护性。

总结

通过本教程,我们学习了如何使用Opis JSON Schema库来验证一个JSON数组,确保其中包含至少一个具有特定固定值(如id为1)的对象。关键在于两个方面:一是通过json_encode和json_decode对PHP数据进行预处理,将其内部的关联数组转换为stdClass对象;二是在JSON Schema定义中,确保contains关键字下的子Schema将type正确设置为object。掌握这些技巧将使您能够更精确、更有效地利用JSON Schema进行数据验证,从而提升应用程序的健壮性。

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2890

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1731

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1564

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

1099

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1546

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1277

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1649

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1309

2023.11.13

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

58

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 9.4万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.1万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号