squidit / array-to-object

使用类型对象属性将数组填充为对象

v1.1.2 2024-05-30 15:33 UTC

This package is auto-updated.

Last update: 2024-09-02 18:16:11 UTC


README

通过将提供的数组键映射到相应的类型类属性名称来从数组数据创建对象。

数组键必须与对象属性名称匹配。

使用示例

<?php

declare(strict_types=1);

use SquidIT\Hydrator\ArrayToObject;
use SquidIT\Hydrator\Class\ClassInfoGenerator;
use SquidIT\Hydrator\Tests\Unit\ExampleObjects\Car\Complete\CarComplete;

$classInfoGenerator = new ClassInfoGenerator();
$hydrator           = new ArrayToObject($classInfoGenerator);

$data = [
    'color'           => 'black',
    'nrOfDoors'       => 4,
    'mileagePerLiter' => 16.3,
    'passengerList'   => ['melvin', 'bert'],
    'manufacturer'    => [
        'addressLine1' => 'Beautiful Street 123',
        'addressLine2' => 'Apartment 1234',
        'city'         => 'Rotterdam',
        'employeeList' => [
            ['employeeName' => 'cecil'],
            ['employeeName' => 'melvin'],
        ],
    ],
    'interCoolers' => [
        [
            'speedRangeMinRpm' => 200,
            'speedRangeMaxRpm' => 2160,
            'isWaterCooled'    => true,
            'speedCategory'    => 'fast',
        ],
        [
            'speedRangeMinRpm' => 100,
            'speedRangeMaxRpm' => 2200,
            'isWaterCooled'    => false,
            'speedCategory'    => 'slow',
        ],
    ],
    'countryEntryDate' => '2015-06-01 13:45:01',
    'extraInfo'        => null,
];

$carComplete = $hydrator->hydrate($data, CarComplete::class);

var_dump($carComplete);

输出

object(SquidIT\Hydrator\Tests\Unit\ExampleObjects\Car\Complete\CarComplete)#6 (9) {
  ["color"]=>
  string(5) "black"
  ["nrOfDoors"]=>
  int(4)
  ["mileagePerLiter"]=>
  float(16.3)
  ["passengerList"]=>
  array(2) {
    [0]=>
    string(6) "melvin"
    [1]=>
    string(4) "bert"
  }
  ["manufacturer"]=>
  object(SquidIT\Hydrator\Tests\Unit\ExampleObjects\Manufacturer\Honda)#21 (4) {
    ["addressLine1"]=>
    string(20) "Beautiful Street 123"
    ["addressLine2"]=>
    string(14) "Apartment 1234"
    ["city"]=>
    string(9) "Rotterdam"
    ["employeeList"]=>
    array(2) {
      [0]=>
      object(SquidIT\Hydrator\Tests\Unit\ExampleObjects\Manufacturer\Employee)#24 (1) {
        ["employeeName"]=>
        string(5) "cecil"
      }
      [1]=>
      object(SquidIT\Hydrator\Tests\Unit\ExampleObjects\Manufacturer\Employee)#10 (1) {
        ["employeeName"]=>
        string(6) "melvin"
      }
    }
  }
  ["interCoolers"]=>
  array(2) {
    [0]=>
    object(SquidIT\Hydrator\Tests\Unit\ExampleObjects\Car\Parts\InterCooler)#14 (4) {
      ["speedRangeMinRpm"]=>
      int(200)
      ["speedRangeMaxRpm"]=>
      int(2160)
      ["isWaterCooled"]=>
      bool(true)
      ["speedCategory"]=>
      enum(SquidIT\Hydrator\Tests\Unit\ExampleObjects\Car\Speed::FAST)
    }
    [1]=>
    object(SquidIT\Hydrator\Tests\Unit\ExampleObjects\Car\Parts\InterCooler)#44 (4) {
      ["speedRangeMinRpm"]=>
      int(100)
      ["speedRangeMaxRpm"]=>
      int(2200)
      ["isWaterCooled"]=>
      bool(false)
      ["speedCategory"]=>
      enum(SquidIT\Hydrator\Tests\Unit\ExampleObjects\Car\Speed::SLOW)
    }
  }
  ["countryEntryDate"]=>
  object(DateTimeImmutable)#39 (3) {
    ["date"]=>
    string(26) "2015-06-01 13:45:01.000000"
    ["timezone_type"]=>
    int(3)
    ["timezone"]=>
    string(3) "UTC"
  }
  ["extraInfo"]=>
  NULL
  ["isInsured"]=>
  bool(true)   <--- object default property and was not present in our data array
}

嵌套对象

如果类属性包含嵌套对象,填充器可以通过读取属性类型来推断对象类型。

在下面的示例中,Car::class 包含一个命名属性 manufacturer,其类型为 Honda::class。在填充时,我们需要提供创建 Honda 对象所需的所有数据。

class Car
{
    public function __construct(
        public string $color,
        public Honda $manufacturer,
    ) {}
}

$data = [
    'color'           => 'black',
    'manufacturer'    => [  // <-- Honda::class
        'name'         => 'Beautiful Street 124',
        'city'         => 'Rotterdam',
        'employeeList' => []
    ],
];

嵌套对象:对象数组

如果类属性包含对象数组,我们需要添加属性属性
SquidIT\Hydrator\Attributes\ArrayOf([CLASSNAME]).

在下面的示例中,Honda::class 包含一个属性 employeeList,应包含 Employee::class 对象的数组。

通过添加属性属性 SquidIT\Hydrator\Attributes\ArrayOf(Employee::class),我们的填充器知道如何填充在 'employeeList' 数组键下找到的数组数据。

use SquidIT\Hydrator\Attributes\ArrayOf;

class Honda implements ManufacturerInterface
{
    /**
     * @param array<int, Employee> $employeeList
     */
    public function __construct(
        public string $name,
        public string $city,
        #[ArrayOf(Employee::class)]
        public array $employeeList,
    ) {}
}

类型转换/将数组值转换为对象属性

重要的是要注意,填充器只适用于只包含类型属性的课程。如果找到非类型属性,将抛出 SquidIT\Hydrator\Exceptions\AmbiguousTypeException 异常。

填充器支持以下属性类型的转换

int

如果字符串只包含数字(允许加号和减号)

bool

以下值将被转换为 true

  • 1 [int]
  • 'true' [string]
  • '1' [string]
  • 'y' [string]
  • 'yes' [string]

以下值将被转换为 false

  • 0 [int]
  • 'false' [string]
  • '0' [string]
  • 'n' [string]
  • 'no' [string]

DateTimeImmutable::class

strtotime() 支持的任何字符串值
注意:作为此库的作者,我感觉没有必要支持 DateTime::class

BackedEnum

支持整数或字符串的枚举值

UnionTypes

❌ 联合类型不受支持,因为我们无法推断具体的对象类型实现。