eddiriarte / oh
一个简单而精致的PHP对象水化器库。
1.0.0
2022-04-10 10:25 UTC
Requires
- php: ^8.1
- ext-ctype: *
Requires (Dev)
- doctrine/collections: ^1.6
- friendsofphp/php-cs-fixer: ^3.8
- illuminate/collections: ^9.7
- phpunit/phpunit: ^9.5
- symfony/var-dumper: ^6.0
README
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复制的。
免责声明
此库仍在积极开发中,其使用可能因优化性能、添加缓存和脱水而改变。