tnapf / jsonmapper
JSON对象映射器
v1.4.0
2023-09-14 16:57 UTC
Requires
- php: >=8.1
Requires (Dev)
- ergebnis/composer-normalize: ^2.31
- fakerphp/faker: ^1.21
- friendsofphp/php-cs-fixer: ^3.16
- jetbrains/phpstorm-attributes: ^1.0
- phpunit/phpunit: ^10.1
- roave/security-advisories: dev-latest
- xheaven/composer-git-hooks: ^3.0
README
JSON Mapper
安装
composer require tnapf/json-mapper
支持类型
- 枚举
- 原始类型
- 对象
- 数组
- 自定义类型(通过 CallbackType)
使用方法
实例化映射器
use Tnapf\JsonMapper\Mapper; $mapper = new Mapper;
创建抽象类
class User { public int $id; public string $username; public string $password; }
将JSON转换为数组并映射类
$user = [ "id" => 1, "username" => ":username:", "password" => ":password:" ]; $mappedUser = $mapper->map($user, User::class);
使用属性进行类型定义
原始类型
对于原始类型,您可以在属性上使用 PrimitiveArray 属性
use Tnapf\JsonMapper\Attributes\PrimitiveType; use Tnapf\JsonMapper\Attributes\PrimitiveArrayType; class User { public int $id; public string $username; public string $password; #[PrimitiveArrayType(name: 'roles', type: PrimitiveType::STRING)] public array $roles; }
// what the new item will look like $user = [ // ... 'roles' => [':name:', ':name:', ':name:'] ];
对象类型
如果您想使数组具有类,可以使用 ObjectArrayType 属性
use Tnapf\JsonMapper\Attributes\ObjectArrayType; class User { public int $id; public string $username; public string $password; #[ObjectArrayType(name: 'roles', type: Role::class)] public array $roles; } class Role { public int $id; public string $name; }
// what the updated item will look like $user = [ // ... 'roles' => [ [ 'id' => 1, 'name' => ':name:' ], [ 'id' => 2, 'name' => ':name:' ], [ 'id' => 3, 'name' => ':name:' ] ] ];
数组枚举类型
use Tnapf\JsonMapper\Attributes\EnumerationArrayType; class User { public int $id; public string $username; public string $password; #[EnumerationArrayType(name: 'roles', type: Role::class))] public array $roles; } enum Role: int { case USER = 1; case ADMIN = 2; case OWNER = 3; }
// what the updated item will look like $user = [ // ... 'roles' => [1, 3] ];
CallbackType
如果您需要为映射类执行特定操作,可以扩展 CallbackType 类以创建自定义类型
use Attribute; use ReflectionException; use Tnapf\JsonMapper\Attributes\MappableType; use Tnapf\JsonMapper\MapperException; use Tnapf\JsonMapper\MapperInterface; #[Attribute(Attribute::TARGET_PROPERTY)] class FriendsType extends MappableType { public function isType(mixed $data): bool { if (!is_array($data)) { return false; } foreach ($data as $item) { if (!$item instanceof User) { return false; } } return true; } /** * @throws ReflectionException * @throws MapperException */ public function map(mixed $data, MapperInterface $mapper): mixed { $friends = []; foreach ($data as $item) { $friend = $mapper->map(User::class, $item); $friends[$friend->username] = $friend; } return $friends; } } class User { public string $username; public string $password; #[FriendsType(name: 'friends', nullable: true)] public array $friends; }
// what the updated item will look like $user = [ // ... 'friends' => [ [ 'username' => ':username:', 'password' => ':password:' ], [ 'username' => ':username:', 'password' => ':password:' ], [ 'username' => ':username:', 'password' => ':password:' ] ] ];
属性大小写转换
由于常见的json命名约定为 snake_case,而PHP的为 camelCase,您可以使用属性将 snake_case 的json属性路由到您的 camelCase 属性。
use Tnapf\JsonMapper\Attributes\SnakeToCamelCase; use Tnapf\JsonMapper\Attributes\PrimitiveType; use Tnapf\JsonMapper\Attributes\PrimitiveArrayType; #[SnakeToCamelCase] class User { public int $id; public string $username; public string $password; #[PrimitiveArrayType(name: 'all_roles', type: PrimitiveType::STRING)] public array $allRoles; }
虽然类中的 allRoles 是 camelCase,但您可以看到下面的JSON使用 snake_case
{
"id": 1,
"username": ":username:",
"password": "1234",
"all_roles": [
"admin",
"user"
]
}