apimatic / jsonmapper
将嵌套的 JSON 结构映射到 PHP 类
Requires
- php: ^5.6 || ^7.0 || ^8.0
- ext-json: *
Requires (Dev)
- phpunit/phpunit: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0
- squizlabs/php_codesniffer: ^3.0.0
- dev-master
- 3.1.4
- 3.1.3
- 3.1.2
- 3.1.1
- 3.1.0
- 3.0.7
- 3.0.6
- v3.0.5
- v3.0.4
- v3.0.3
- v3.0.2
- v3.0.1
- v3.0.0
- v2.0.3
- v2.0.2
- v2.0.1
- v2.0.0
- v1.3.1
- v1.3.0
- v1.2.0
- v1.1.0
- v1.0.2
- v1.0.1
- v1.0.0
- v0.10.0
- v0.9.0
- v0.8.0
- v0.7.0
- v0.6.1
- v0.6.0
- v0.5.0
- v0.4.4
- v0.4.3
- v0.4.2
- v0.4.1
- v0.4.0
- v0.3.0
- v0.2.1
- v0.2.0
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
- dev-merge-release-notification
- dev-release-notification
This package is auto-updated.
Last update: 2024-09-12 05:03:40 UTC
README
从 JSON 网络服务获取数据,并将其转换为嵌套对象和数组 - 使用您自己的模型类。
从基础对象开始,它将 JSON 数据映射到类属性,将它们转换为正确的基本类型或对象。
它有点像 PHP 的 SoapClient
提供的本地 SOAP 参数映射,但用于 JSON。注意,它不依赖于任何模式,只依赖于您的类定义。
类型检测通过解析类属性的 @var
文档注释以及设置方法中的类型提示来实现。如果通过一些配置设置(如 opcache.save_comments=0
)或任何其他类似配置丢弃了文档注释或一般注释,将抛出异常,阻止任何进一步的操作。
您不需要通过添加 JSON 特定代码来修改您的模型类;它通过解析已存在的文档注释自动工作。
关键词:反序列化,数据填充
内容
优缺点
优点
- IDE 中的自动完成
- 很容易向数据模型类添加便捷方法
- 您的 JSON API 可能会更改,但您的模型可以保持不变 - 不会破坏使用模型类的应用程序。
缺点
模型类需要手动编写
由于 JsonMapper 不依赖于任何模式信息(例如来自 json-schema),模型类不能自动生成。
使用方法
基本用法
- 注册一个可以加载 PSR-0 兼容类的自动加载器。
- 创建一个
JsonMapper
对象实例 - 根据您的数据调用
map
或mapArray
方法
映射一个普通对象
<?php require 'autoload.php'; $mapper = new JsonMapper(); $contactObject = $mapper->map($jsonContact, new Contact()); ?>
映射对象数组
<?php require 'autoload.php'; $mapper = new JsonMapper(); $contactsArray = $mapper->mapArray( $jsonContacts, new ArrayObject(), 'Contact' ); ?>
示例
来自地址簿网络服务的 JSON
{ 'name':'Sheldon Cooper', 'address': { 'street': '2311 N. Los Robles Avenue', 'city': 'Pasadena' } }
您本地的 Contact
类
<?php class Contact { /** * Full name * @var string */ public $name; /** * @var Address */ public $address; } ?>
您本地的 Address
类
<?php class Address { public $street; public $city; public function getGeoCoords() { //do something with the $street and $city } } ?>
您的应用程序代码
<?php $json = json_decode(file_get_contents('http://example.org/bigbang.json')); $mapper = new JsonMapper(); $contact = $mapper->map($json, new Contact()); echo "Geo coordinates for " . $contact->name . ": " . var_export($contact->address->getGeoCoords(), true); ?>
让 JsonMapper 为您创建实例
映射一个普通对象(与 map
工作方式类似)
$mapper = new JsonMapper(); $contactObject = $mapper->mapClass($jsonContact, 'Contact');
映射对象数组(与 mapArray
工作方式类似)
$mapper = new JsonMapper(); $contactsArray = $mapper->mapClassArray($jsonContacts, 'Contact');
以任何类型组合映射值,例如 oneOf(string,int) 或 anyOf(string,Contact)
$mapper = new JsonMapper(); $contactObject = $mapper->mapFor($value, 'oneOf(string,Contact)');
属性类型文档
JsonMapper
使用多个来源来检测属性的正确类型
检查设置方法(
set
+ucwords($propertyname)
)。下划线使下一个字母大写,这意味着对于 JSON 属性
foo_bar_baz
,使用setFooBarBaz
的设置方法。如果方法签名中具有类型提示,则使用此类型。
public function setPerson(Contact $person) {...}
检查方法的文档注释以查找
@param $type
注释。/** * @param Contact $person Main contact for this application */ public function setPerson($person) {...}
如果无法检测到类型,则将普通 JSON 值传递给设置方法。
类属性的
@var $type
文档注释/** * @var \my\application\model\Contact */ public $person;
请注意,属性必须是公共的才能直接使用。
如果无法检测到类型,则属性将获取普通 JSON 值。
如果找不到属性,JsonMapper会尝试以不区分大小写的方式查找属性。一个JSON属性
isempty
将被映射到PHP属性isEmpty
。
要映射JSON键到一个任意命名的类属性,您可以使用@maps
注解
/** * @var \my\application\model\Person * @maps person_object */ public $person;
支持的类型名称
- 简单类型
string
bool
,boolean
int
,integer
float
array
object
- 类名称,包括和不包括命名空间
- 简单类型和类名称的数组
int[]
Contact[]
- 简单类型和类名称的ArrayObjects
ContactList[Contact]
NumberList[int]
- 可空类型
int|null
- 如果JSON中的值是null
,则为null
,否则为整数
ArrayObjects和扩展类被视为数组。
没有类型或类型为mixed
的变量将直接设置JSON值,而不进行任何转换。
有关更多信息,请参阅phpdoc的类型文档。
简单类型映射
当需要创建对象但JSON只包含简单类型(例如字符串、浮点数、布尔值)时,此值将被传递到类的构造函数中。示例
PHP代码
/** * @var DateTime */ public $date;
JSON
{"date":"2014-05-15"}
这将导致调用new DateTime('2014-05-15')
。
自定义属性初始化
您可以使用@factory
注解来指定一个自定义方法,该方法将用于获取分配给属性的值。
/** * @factory MyUtilityClass::createDate */ public $date;
在此,MyUtilityClass
中的createDate
方法使用date
属性的原始值和工厂方法返回的值调用。
当使用is_callable
测试时,工厂方法应该返回true,否则将抛出异常。
工厂注解可以与其他注解(如@var
)一起使用;然而,只有工厂方法创建的值将被使用,而其他属性的类型提示和初始化方法将被忽略。
日志记录
JsonMapper的setLogger()
方法支持所有PSR-3兼容的日志记录实例。
被记录的事件
- JSON数据包含一个键,但类没有为该键定义属性或setter方法。
- 由于它们是受保护的或私有的,因此既不能从外部设置setter,也不能设置属性
处理无效或缺失数据
在开发过程中,API经常更改。为了通知此类更改,JsonMapper可能会在数据缺失或尚未知的情况下抛出异常。
未知属性
当JsonMapper看到JSON数据中的属性未在PHP类中定义时,您可以通过设置$bExceptionOnUndefinedProperty
来让它抛出异常
$jm = new JsonMapper(); $jm->bExceptionOnUndefinedProperty = true; $jm->map(...);
要自己处理未知属性,您可以在类上设置一个方法作为收集方法
$jm = new JsonMapper(); $mapper->sAdditionalPropertiesCollectionMethod = 'addAdditionalProperty'; $jm->map(...);
在此,将使用name
和value
参数调用addAdditionalProperty()
方法。
缺失属性
您可以在PHP类的属性的docblock中放置@required
来标记属性为“必需”
/** * @var string * @required */ public $someDatum;
当JSON数据不包含此属性时,如果激活了$bExceptionOnMissingData
,JsonMapper将抛出异常
$jm = new JsonMapper(); $jm->bExceptionOnMissingData = true; $jm->map(...);
将数组传递给 map()
您可能希望将您通过调用得到的数组数据传递给map()
json_decode($jsonString, true)
默认情况下,由于map()
需要对象作为第一个参数,JsonMapper将抛出异常。您可以通过设置$bEnforceMapType
为false
来绕过这一点
$jm = new JsonMapper(); $jm->bEnforceMapType = false; $jm->map(...);
处理多态响应
JsonMapper允许您根据区分字段将JSON对象映射到派生类。区分字段的值用于决定此JSON对象应映射到哪个类。
您本地的Person
类
<?php /** * @discriminator type * @discriminatorType person */ class Person { public $name; public $age; public $type; }
您本地的Employee
类
<?php /** * @discriminator type * @discriminatorType employee */ class Employee extends Person { public $employeeId; }
您的应用程序代码
$mapper = new JsonMapper(); $mapper->arChildClasses['Person'] = ['Employee']; $mapper->arChildClasses['Employee'] = []; $person = $mapper->mapClass($json, 'Person');
现在,如果JSON中type
键的值是"person"
,则返回Person
类的实例。然而,如果type
是"employee"
,则返回Employee
类的实例。
在使用区分符之前,类必须在 arChildClasses
中注册。
注意,在对象层次结构中只能有一个区分符字段。
如果多态类作为字段或数组嵌入,则多态响应也可以工作。
要映射类数组,请使用 mapArrayClass
,它将通过检查 discriminatorType
值来创建正确的类型对象。
安装
支持的 PHP 版本
- PHP 5.6
- PHP 7.0
- PHP 7.1
- PHP 7.2
- PHP 7.4
- PHP 8.0
- PHP 8.1
- PHP 8.2
安装软件包
来源:Packagist
$ composer require apimatic/jsonmapper
相关软件
- Jackson的数据绑定(Java版)
- Johannes Schmitt 序列化器(PHP版)
关于 JsonMapper
许可证
JsonMapper 采用 OSL 3.0 许可。
编码风格
JsonMapper 遵循 PEAR 编码标准。