rogerthomas84/dtoinflator

DtoInflator是一个库,可以将数组或对象膨胀成相应的模型。

2.0.1 2021-01-18 11:03 UTC

This package is auto-updated.

Last update: 2024-09-18 18:49:33 UTC


README

DtoInflator是一个将数组或泛型对象转换为DTO的有用库。

最初编写这个库是为了帮助简化API服务响应的管理。

使用方法

创建您的模型,扩展DtoInflatorAbstract

如果您需要子模型,将protected $keyToClassMap属性添加到您的父模型中,将键名映射到完全限定的类名。这告诉库识别键并需要膨胀特定模型。

所有模型都应该扩展DtoInflatorAbstract

如果您有一个名为'favourite'的DTO属性需要子模型,可以使用以下方式映射它

protected $keyToClassMap = [
    'favourite' => '\MyNamespace\Favourite'
];

如果您需要一个模型的数组(例如,某人有多种最喜欢的项目),您可以在映射中的类名后简单地追加[]

因此,如果您有一个名为'favourites'的属性,它是子模型的数组,键到类映射应如下所示

protected $keyToClassMap = [
    'favourites' => '\MyNamespace\Favourite[]'
];

有时您可能想要将属性的名称更改为其他名称,例如在API响应的情况下,您可能想要将下划线键更改为驼峰式。为此,只需在您的模型中公开fieldToFieldMap变量。其中键是原始名称,值是在DTO中使用的新的键。

请注意,新命名的键仅在膨胀时使用。

protected $fieldToFieldMap = [
    'my_underscore_key' => 'myUnderscoreKey'
];

您可能还希望偶尔缩短键。为此,您可以在膨胀方法中传递第二个参数,定义这些键需要映射的位置。

protected $longToShortKeys = [
    'user_first_name' => 'fn', // would map the key 'user_first_name' to use 'fn'
    'user_last_name' => 'ln' // would map the key 'user_last_name' to use 'ln'
];

示例

tests/DtoInflatorTests/TestModels目录中存在示例模型。

膨胀

您可以通过调用inflateSingleArray并传递数据数组来膨胀单个记录,或者如果您有一个对象(例如stdClass),您可以使用inflateSingleObject

<?php
namespace MyNamespace;

class Person extends \DtoInflator\DtoInflatorAbstract
{
    public $name;
    public $age;
}

$data = [
    'name' => 'Joe',
    'age' => 35
];
$inflated = Person::inflateSingleArray($data);

同样,您可以通过调用inflateMultipleArrays并传递数组数组来膨胀多个记录,或者如果您使用的是上面的对象,可以使用inflateMultipleObjects方法。

<?php
namespace MyNamespace;

class Person extends \DtoInflator\DtoInflatorAbstract
{
    public $name;
    public $age;
}

$data = [
    [
        'name' => 'Joe',
        'age' => 35
    ],
    [
        'name' => 'Jane',
        'age' => 34
    ]
];
$inflated = Person::inflateSingleArray($data);

字段映射

如果传递给膨胀方法的键在对象中找不到,它会被添加到unmappedFields数组中。同样,如果您在膨胀后尝试从对象中请求数据且属性找不到,内部抽象方法__get($name)将检查unmappedFields以查找相应的值。

理论上您不需要声明变量。但这显然是不建议的。然而,这意味着属性实际上不必是public,它们可以是protected,但绝对不能是private

更复杂的模型

如果您需要更复杂的模型,可以使用类似以下的方法

<?php
namespace MyNamespace;

class Favourite extends \DtoInflator\DtoInflatorAbstract
{
    /**
     * @var string
     */
    public $candy;
}

class ColorItem extends \DtoInflator\DtoInflatorAbstract
{
    /**
     * @var string
     */
    public $name;
}

class Person extends \DtoInflator\DtoInflatorAbstract
{
    /**
     * @var string
     */
    public $firstName;

    /**
     * @var int
     */
    public $age;

    /**
     * @var Favourite
     */
    public $favs;

    /**
     * @var ColorItem[]
     */
    public $colors;

    /**
     * @param array
     */
    protected $fieldToFieldMap = [
        'name' => 'firstName' // maps the source key of `name` to the object property of `firstName`
    ];

    /**
     * @param array
     */
    protected $keyToClassMap = [
        'favs' => '\MyNamespace\Favourite',  // maps the object property of `favs` to an instance of the `Favourite` object
        'colors' => '\MyNamespace\ColorItem[]'   // maps the object property of `colors` to an array of `ColorItem` objects
    ];
}

$data = [
    'name' => 'Joe',
    'age' => 35,
    'favs' => [
        'candy' => 'chocolate'
    ],
    'colors' => [
        [
            'name' => 'blue'
        ],
        [
            'name' => 'red'
        ]
    ]
];
$inflated = Person::inflateSingleArray($data);

// Or, if you're using an object initially.
$candyBar = new stdClass();
$candyBar->candy = 'chocolate';
$colorOne = new stdClass();
$colorOne->name = 'blue';
$colorTwo = new stdClass();
$colorTwo->name = 'red';

$data = new stdClass();
$data->name = 'Joe';
$data->age = 35;
$data->favs = [
    $candyBar
];
$data->colors = [
    $colorOne,
    $colorTwo
];
$inflated = Person::inflateSingleObject($data);

运行单元测试

./vendor/bin/phpunit -c phpunit.xml