一个简单而精致的PHP对象水化器库。

维护者

详细信息

github.com/eddiriarte/oh

源代码

问题

安装: 1

依赖项: 0

建议者: 0

安全: 0

星标: 0

关注者: 2

分支: 0

开放问题: 0

类型:项目

1.0.0 2022-04-10 10:25 UTC

This package is auto-updated.

Last update: 2024-09-10 16:08:40 UTC


README

OH Logo

OH

一个简单而精致的PHP对象水化器库。

安装

composer require eddiriarte/oh

用法

此库允许将数据从(嵌套)数组格式转换为正确的PHP对象。

// Define your class(es):
class Person
{
    public function __construct(
        private string $firstName,
        private string $lastName
    ) {}
    
    //... here you might define getters/setters 
}

// Initialize hydrator manager:
$manager = new \EddIriarte\Oh\Manager();

// Execute hydration:
$person = $manager->hydrate(Person::class, ['first_name' => 'Bruce', 'last_name' => 'Wayne']);

assert($person instanceof Person);

数组键情况

默认行为是将数组中的snake-case键映射到类属性/参数名称。但是,在管理器中,随时可以配置此行为。

use EddIriarte\Oh\Manager;

$snakeCaseManager = new Manager(['source_naming_case' => StringCase::SnakeCase]); // default behaviour
$person1 = $snakeCaseManager->hydrate(Person::class, ['first_name' => 'Bruce', 'last_name' => 'Wayne']);

$camelCaseManager = new Manager(['source_naming_case' => StringCase::CamelCase]);
$person2 = $camelCaseManager->hydrate(Person::class, ['firstName' => 'Bruce', 'lastName' => 'Wayne']);

$studlyCaseManager = new Manager(['source_naming_case' => StringCase::StudlyCase]);
$person3 = $studlyCaseManager->hydrate(Person::class, ['FirstName' => 'Bruce', 'LastName' => 'Wayne']);

$kebabCaseManager = new Manager(['source_naming_case' => StringCase::KebabCase]);
$person4 = $kebabCaseManager->hydrate(Person::class, ['first-name' => 'Bruce', 'last-name' => 'Wayne']);

$anyCaseManager = new Manager(['source_naming_case' => StringCase::AnyCase]);
$person5 = $anyCaseManager->hydrate(Person::class, ['firstName' => 'Bruce', 'last_name' => 'Wayne']);

数据结构对象

如果由于某些原因,您的类没有提供相应的构造方法,那么水化器将尝试填充匹配的类属性。

// Define your class(es):
class Person
{
    private string $firstName;
    private string $lastName;
    
    //... here you might define getters/setters 
}

// Initialize hydrator manager:
$manager = new \EddIriarte\Oh\Manager();

// Execute hydration:
$person = $manager->hydrate(Person::class, ['first_name' => 'Bruce', 'last_name' => 'Wayne']);

assert($person instanceof Person);

此外,管理器允许指定要考虑的属性的可见性

use EddIriarte\Oh\Manager;
use EddIriarte\Oh\Enums\PropertyVisibility;

class ReadOnlyPerson
{
    public readonly string $firstName;
    public readonly string $lastName;
    public int $age;
}

// Initialize hydrator manager:
$manager = new Manager(['property_visibility' => PropertyVisibility::ReadOnly]);

// Execute hydration:
$person = $manager->hydrate(ReadOnlyPerson::class, ['first_name' => 'Bruce', 'last_name' => 'Wayne', 'age' => 44]);

var_dump($person);

// class ReadOnlyPerson#700 (3) {
//   public readonly string $firstName =>
//   string(5) "Bruce"
//   public readonly string $lastName =>
//   string(5) "Wayne"
//   public int $age =>
//   *uninitialized*
// }

嵌套对象

水化器遍历所有属性/参数,并尝试初始化嵌套类型

use EddIriarte\Oh\Manager;
use EddIriarte\Oh\Enums\PropertyVisibility;

class Person
{
    public function __construct(
        private string $firstName,
        private string $lastName
    ) {}
}

class Hero
{
    public function __construct(
        private string $name,
        private Person $alias
    ) {}
}

// Execute hydration:
$hero = (new Manager())->hydrate(
    Hero::class,
    [
        'name' => 'Batman',
        'alias' => [
            'first_name' => 'Bruce', 
            'last_name' => 'Wayne',
        ],
    ]
);

列表、字典、数组

水化器已经支持对象列表的填充。要将嵌套项水化到特定的类中,需要提供额外的信息,这些信息可以通过PHP属性提供。

use EddIriarte\Oh\Attributes\ListMemberType;
use EddIriarte\Oh\Enums\PropertyVisibility;
use EddIriarte\Oh\Manager;

class Hero
{
    public function __construct(private string $name)
    {}
}

class HeroTeam
{
    public function __construct(
        private string $name,
        #[ListMemberType(Hero::class)]
        private array $heroes
    ) {}
}

$team = (new Manager())->hydrate(
    HeroTeam::class,
    [
        'name' => 'Batman & Robin',
        'heroes' => [
            ['name' => 'Batman'], 
            ['name' => 'Robin'],
        ],
    ]
);

也可以使用可实例化的Arrayable类而不是数组。在这个例子中,我们使用Doctrine的ArrayCollection,但也可以使用Laravel集合完成。

use Doctrine\Common\Collections\ArrayCollection;

use EddIriarte\Oh\Attributes\ListMemberType;
use EddIriarte\Oh\Enums\PropertyVisibility;
use EddIriarte\Oh\Manager;

class Hero
{
    public function __construct(private string $name)
    {}
}

class HeroTeam
{
    public function __construct(
        private string $name,
        #[ListMemberType(Hero::class)]
        private ArrayCollection $heroes
    ) {}
}

$team = (new Manager())->hydrate(
    HeroTeam::class,
    [
        'name' => 'Batman & Robin',
        'heroes' => [
            ['name' => 'Batman'], 
            ['name' => 'Robin'],
        ],
    ]
);

配置

仍在进行中...

致谢

字符串大小写函数是从Laravel复制的。

免责声明

此库仍在积极开发中,其使用可能因优化性能、添加缓存和脱水而改变。