prinsfrank/object-resolver

轻松将数组/请求/json 等转换为类型化且经过验证的对象

v0.0.3 2024-09-07 21:39 UTC

This package is auto-updated.

Last update: 2024-09-07 21:40:33 UTC


README

对象解析器

GitHub PHP Version Support Packagist Downloads codecov PHPStan Level

从请求、json 等数据解析对象

设置

注意 确保您正在运行 PHP 8.3 或更高版本以使用此包

要立即开始,请在您的 composer 项目中运行以下命令;

composer require prinsfrank/object-resolver

或者仅用于开发;

composer require prinsfrank/object-resolver --dev

使用场景

处理传入请求

给定一个简单的登录控制器,我们有一个以下请求对象

<?php declare(strict_types=1);

readonly class LogInRequest {
    public function __construct(
        #[SensitiveParameter] private string $email,
        #[SensitiveParameter] private string $password,
    ) {
    }
}

控制器看起来像这样

<?php declare(strict_types=1);

readonly class LogInController {
    public function __invoke(LogInRequest $logInRequest){
        // Handle authentication
    }
}

我们需要根据请求数据自动连接传入的请求。这就是这个包的作用所在!

如果有一个容器可用,我们就可以添加一个动态的抽象具体绑定

final class RequestDataProvider implements ServiceProviderInterface {
    public function provides(string $identifier): bool {
        return is_a($identifier, RequestData::class, true);
    }

    public function register(string $identifier, DefinitionSet $resolvedSet): void {
        $resolvedSet->add(
            new Concrete(
                $identifier,
                static function (ObjectResolver $objectResolver, ServerRequestInterface $serverRequest) use ($identifier) {
                    $requestData = match ($serverRequest->getMethod()) {
                        'GET' => $serverRequest->getQueryParams(),
                        'POST', 
                        'PATCH', 
                        'PUT' => $serverRequest->getParsedBody(),
                        default => [],
                    };

                    return $objectResolver->resolveFromParams($identifier, $requestData);
                },
            )
        );
    }
}

大小写转换

由于不同技术栈之间的代码约定可能不同,因此可以自动在大小写之间转换。

假设有一个 HTML 表单,其名称为 user_name,但在后端我们的模型参数为 $userName。这可以通过提供参数 $enforcePropertyNameCasing$convertFromParamKeyCasing 自动转换

final class ObjectResolverServiceProvider implements ServiceProviderInterface {
    #[Override]
    public function provides(string $identifier): bool {
        return $identifier === ObjectResolver::class;
    }

    /** @throws InvalidArgumentException */
    #[Override]
    public function register(string $identifier, DefinitionSet $resolvedSet): void {
        $resolvedSet->add(
            new Concrete(
                $identifier,
                fn () => new ObjectResolver(Casing::camel, Casing::snake)
            )
        );
    }
}

API 等的 JSON

TODO: 编写文档