radebatz/object-mapper

(Json) 对象映射器。

v1.2.0 2022-05-01 22:15 UTC

README

一个简单的库,用于将 JSON 反序列化为 (嵌套) PHP 数组 / 对象。

Build Status Coverage Status License: MIT

需求

安装

您可以使用 Composer 或直接 下载发行版

Composer

首选方法是使用 composer。如果您尚未安装 composer,请按照 安装说明 进行操作。

Composer 安装后,在项目根目录中执行以下命令以安装此库

composer require radebatz/object-mapper

用法

使用 getXXX()/setXXX() 的简单模型

use Radebatz\ObjectMapper\ObjectMapper;

class MyClass 
{
    protected $foo;
    
    public function getFoo()
    {
        return $this->foo;
    }
    
    public function setFoo($foo) 
    {
        $this->foo = $foo;
    }
}

    
$objectMapper = new ObjectMapper();

$json = '{"foo":"bar"}';

/** @var \MyClass $obj */
$obj = $objectMapper->map($json, \MyClass::class);

echo $obj->getFoo(); // 'bar'

使用接口的值联合

use Radebatz\ObjectMapper\ObjectMapper;
use Radebatz\ObjectMapper\ValueTypeResolverInterface;

interface ValueInterface
{
    public function getType(): string;
}

class Tree implements ValueInterface
{
    public function getType(): string
    {
        return "tree";
    }
}

class Flower implements ValueInterface
{
    public function getType(): string
    {
        return "flower";
    }
}

$objectMapper = new ObjectMapper();
$objectMapper->addValueTypeResolver(
    new class() implements ValueTypeResolverInterface {
        public function resolve($className, $json): ?string
        {
            if (is_object($json) && \ValueInterface::class == $className) {
                if (property_exists($json, 'type')) {
                    switch ($json->type) {
                        case 'tree':
                            return \Tree::class;
                        case 'flower':
                            return \Flower::class;
                    }
                }
            }

            return null;
        }
    }
);

$json = '{"type": "flower"}';

/** @var \ValueInterface $obj */
$obj = $objectMapper->map($json, \ValueInterface::class);

echo get_class($obj); // '\Flower'
    $objectMapper->addValueTypeResolver(
        new class() implements ValueTypeResolverInterface {
            public function resolve($className, $json): ?string
            {
                if (is_object($json) && PopoInterface::class == $className) {
                    if (property_exists($json, 'foo')) {
                        return AnotherPopo::class;
                    }

                    return SimplePopo::class;
                }

                return null;
            }
        }
    );

配置

ObjectMapper 类将数组(映射)作为第一个构造函数参数,允许在映射数据时自定义行为。所有选项名称(键)都定义为类常量。

OPTION_STRICT_TYPES

强制执行内置数据类型的严格类型检查(不包括 array)。

默认:true

OPTION_STRICT_COLLECTIONS

强制执行数组上的严格类型检查。

默认:true

OPTION_STRICT_NULL

强制检查 null 值分配。

默认:true

OPTION_IGNORE_UNKNOWN

启用/禁用报告未映射的属性(将抛出 ObjectMapperException)。

默认:true

OPTION_VERIFY_REQUIRED

如果启用,则检查所有带有 @required 注解的属性是否已映射(将抛出 ObjectMapperException)。

默认:false

OPTION_INSTANTIATE_REQUIRE_CTOR

如果禁用,当常规 new $class() 失败时,对象实例化将回退到 ReflectionClass::newInstanceWithoutConstructor()。此外,如果设置,它将强制执行构造函数参数检查,如果将标量反序列化为对象。

默认:true

OPTION_UNKNOWN_PROPERTY_HANDLER

可选的可调用函数,用于处理未知/不可映射的属性。签名

function ($obj, $key, $value) {}

返回值应该是属性名称或 null

默认:null

OPTION_VARIADIC_SETTER

如果启用,设置列表值将允许在模型上使用可变参数(需要 5.2 >= PropertyAccess)。

class Model {
  private $list = [];
  public function setList(ListModel ... $listModels) {
    $this->list = $listModels;  
  }
}

返回值应该是属性名称或 null

默认:false

测试

此包受优秀的 jsonmapper 包的启发。为了评估其功能,测试文件夹包含一个适配器,允许您在 jsonmapper 测试套件中运行 json-object-manager 代码库。

为此您运行

rm -rf vendor/netresearch/jsonmapper && composer install --prefer-source
./vendor/bin/phpunit -c phpunit.xml.jsonmapper

并非所有测试都通过,因为此库还支持映射标量值。目前运行测试的结果是

Tests: 104, Assertions: 249, Errors: 2, Failures: 14.  (jsonmapper 4.x)

测试使用自定义的 JsonMapper 类,该类内部使用 ObjectMapper