web-fu/anymapper

一个库,允许将对象和数组映射到具有强类型支持和模式检测的对象和数组。

v2.0.1 2024-06-23 22:26 UTC

This package is auto-updated.

Last update: 2024-09-16 15:38:17 UTC


README

Latest Stable Version PHP Version Require Test status Static analysis status Code style status

一个库,允许将对象和数组映射到具有强类型支持和模式检测的对象和数组。

AnyMapper可以获取各种数据输入(对象、数组及其组合),并为目标对象或数组注入数据,确保在整个过程中安全地处理数据类型。
AnyMapper可以检测和从公共属性、标准getter / setter、构造函数和类工厂中提取数据,并可选择执行智能数据转换(例如:从字符串到日期时间)。
AnyMapper不会干扰私有或受保护属性或方法,也不能保证生成的对象处于“有效状态”。

安装

web-fu/anymapper可在Packagist上找到,并可通过Composer进行安装。

composer require web-fu/anymapper

需要PHP 8.1或更高版本。

示例

简单映射

final class MyClass
{
    private string $foo;
    public string $bar;

    public function setFoo(string $foo): MyClass {
        $this->foo = $foo . ' and I was set in a setter';
        return $this;
    }

    public function getFoo(): string
    {
        return $this->foo;
    }
}

$source = [
    'foo' => 'I am foo',
    'bar' => 'I am bar',
];

// Fill an existing class
$destination = new MyClass();

(new \WebFu\AnyMapper\AnyMapper())
    ->map($source)
    ->into($destination)
    ->run();

echo $destination->getFoo(); // I am foo and I was set in a setter
echo PHP_EOL;
echo $destination->bar; // I am bar;
echo PHP_EOL;

// Create a new object of a class
$destination = (new \WebFu\AnyMapper\AnyMapper())
    ->map($source)
    ->as(MyClass::class)
    ->run();

echo $destination->getFoo(); // I am foo and I was set in a setter
echo PHP_EOL;
echo $destination->bar; // I am bar;
echo PHP_EOL;

转换策略

// Use a strategy to customize mapping
final class MyClass
{
    public DateTime $value;
}

$source = [
    'value' => '2022-12-01',
];

$destination = (new \WebFu\AnyMapper\AnyMapper())
    ->map($source)
    ->using(
        (new \WebFu\AnyMapper\Strategy\AllowedCastingStrategy())
            ->allow('string', DateTime::class)
    )
    ->as(MyClass::class)
    ->run();

echo $destination->value->format('Y-m-d H:i:s'); // 2022-12-01 00:00:00
echo PHP_EOL;

通过回调进行转换

final class MyClass
{
    public int $value;
}

$source = [
    'value' => true,
];

$destination =  (new \WebFu\AnyMapper\AnyMapper())
    ->map($source)
    ->using(
        (new \WebFu\AnyMapper\Strategy\CallbackCastingStrategy())
            ->addMethod(
                'bool',
                'int',
                fn (bool $value) => (int) $value,
            )
    )
    ->as(MyClass::class)
    ->run();

echo $destination->value; // 1

DocBlock类型支持

// Use a strategy to customize mapping
final class MyClass
{
    /** @var DateTime */
    public $value;
}

$source = [
    'value' => '2022-12-01',
];

$destination = (new \WebFu\AnyMapper\AnyMapper())
    ->map($source)
    ->using(
        (new \WebFu\AnyMapper\Strategy\DocBlockDetectStrategy())
    )
    ->as(MyClass::class)
    ->run();

echo $destination->value->format('Y-m-d H:i:s'); // 2022-12-01 00:00:00
echo PHP_EOL;

序列化

// Perform a standard serialization
final class Bar
{
    private string $element;

    public function getElement(): string
    {
        return $this->element;
    }

    public function setElement(string $element): Bar
    {
        $this->element = $element;

        return $this;
    }
}

final class Foo
{
    /** @var Bar[] */
    private array $bars;

    /**
     * @return array
     */
    public function getBars(): array
    {
        return $this->bars;
    }

    /**
     * @param array $bars
     * @return Foo
     */
    public function setBars(array $bars): Foo
    {
        $this->bars = $bars;
        return $this;
    }
}

$foo = new Foo();
$foo->setBars([
    (new Bar())->setElement('string'),
]);

$destination =  (new \WebFu\AnyMapper\AnyMapper())
    ->map($foo)
    ->serialize();

var_export($destination);
/*
array (
  'bars' =>
  array (
    0 =>
    array (
      'element' => 'string',
    ),
  ),
)
*/

查看/examples文件夹中的完整示例