apie/object-access-normalizer

此包已被弃用,不再维护。未建议替代包。
此包的最新版本(dev-main)没有可用的许可证信息。

对象访问 + Symfony规范化器,用于将设置器/获取器映射到对象。

dev-main 2021-02-10 09:58 UTC

This package is auto-updated.

Last update: 2022-06-12 09:55:17 UTC


README

Scrutinizer Code Quality Build Status

此包是Apie库的一部分。代码在一个monorepo中维护,因此需要将PR发送到monorepo

文档

与Symfony Serializer一起使用

最简单的用法是将ApieObjectAccessNormalizer添加到Symfony serializer的构造函数中。

<?php
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
use Symfony\Component\Serializer\Serializer;
use Apie\ObjectAccessNormalizer\Normalizers\ApieObjectAccessNormalizer;
use Apie\ObjectAccessNormalizer\ObjectAccess\ObjectAccess;

$serializer = new Serializer(
    [
        new DateTimeNormalizer(),
        new ApieObjectAccessNormalizer(),
        new ArrayDenormalizer(),
    ],
    [new JsonEncoder()]
);

class Example
{
    private $number;

    private $stringValue = '<no value set>';

    public function __construct(int $number)
    {
        $this->number = $number;
    }

    public function setStringValue(string $stringValue)
    {
        $this->stringValue = $stringValue;
    }

    public function getNumber(): int
    {
        return $this->number;
    }

    public function getStringValue(): string
    {
        return $this->stringValue;
    }
}

$instance = new Example(12);
// returns array['number' => 12, 'stringValue' => '<no value set>']
var_dump($serializer->serialize($instance, 'json'));
// returns new Example(12)
var_dump($serializer->deserialize(['number' => 12], Example::class, 'json'));
// throws validation error with errors => ['number' =>' must be one of "int" ("invalid" given)']
$serializer->deserialize(['number' => 'invalid'], Example::class, 'json');
// calls setStringValue("blah") on $instance
$serializer->deserialize(['stringValue' => 'text'], Example::class, 'json', ['object_to_populate' => $instance]);
// use a different object access on $instance to set private properties that have no public setter.
$serializer->deserialize(['number' => '15'], Example::class, 'json', ['object_to_populate' => $instance, 'object_access' => new ObjectAccess(false)]);

除非调用上下文选项 'object_to_populate',否则它将首先尝试通过读取构造函数参数来创建一个新对象。之后,它将检查所有设置器。如果设置器抛出错误,则该错误被视为验证错误,并将返回包含错误结构的验证异常。

ObjectAccess还能读取PHP 7.4+中的属性类型提示和由composer包phpdocumentor/reflection-docblock提供的php docblocks。

驼峰式键

默认情况下,属性名与键相同。我们可以在ApieObjectAccessNormalizer类中通过提供一个实现Symfony\Component\Serializer\NameConverter\NameConverterInterface的类来覆盖此行为。

<?php
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
use Symfony\Component\Serializer\Serializer;
use Apie\ObjectAccessNormalizer\Normalizers\ApieObjectAccessNormalizer;
use Apie\ObjectAccessNormalizer\ObjectAccess\ObjectAccess;

$serializer = new Serializer(
    [
        new DateTimeNormalizer(),
        new ApieObjectAccessNormalizer(new ObjectAccess(), new CamelCaseToSnakeCaseNameConverter()),
        new ArrayDenormalizer(),
    ],
    [new JsonEncoder()]
);
$instance = new Example(12);
// returns array['number' => 12, 'string_value' => '<no value set>']
var_dump($serializer->serialize($instance, 'json'));

高级用法

在许多情况下,您可能只想使用ObjectAccess,并只为特定类或接口使用不同的ObjectAccessInterface实现。为此,我们创建了GroupedObjectAccess。

<?php

use Illuminate\Database\Eloquent\Model;
use W2w\Laravel\LaravelApie\ObjectAccess\EloquentModelAccess;
use Apie\ObjectAccessNormalizer\ObjectAccess\GroupedObjectAccess;
use Apie\ObjectAccessNormalizer\ObjectAccess\ObjectAccess;
use Apie\ObjectAccessNormalizer\ObjectAccess\SelfObjectAccess;
use Apie\ObjectAccessNormalizer\ObjectAccess\SelfObjectAccessInterface;

$objectAccess = new GroupedObjectAccess(
    new ObjectAccess,
    [
        // For SomeClass we can read private properties/getters
        SomeClass::class => new ObjectAccess(false, true),
        // for any class that implements SelfobjectAccessInterface we use SelfObjectAccess
        SelfObjectAccessInterface::class => new SelfObjectAccess(),
        // does not exist in this package, just an example. Eloquent models are notorious for the amount of magic.
        Model::class => new EloquentModelObjectAccess(),
]

);

可用的对象访问实现

  • CachedObjectAccess:用于性能原因缓存结果的装饰器。
  • FilteredObjectAccess:过滤您可以实际使用的字段。另一个装饰器
  • GroupedObjectAccess:请参阅高级用法。可以根据类使用不同的ObjectAcces实例
  • ObjectAccess:默认对象访问。检查公共属性和公共设置器/获取器。
  • SelfObjectAccess:适用于实现SelfObjectAccessInterface的类,因此该类可以自己告诉它可以访问什么。
  • LocalizationAwareObjectAccess:可用于具有本地化感知字段的对象。

本地化

从版本2开始,我们添加了本地化支持。在您的简单对象中添加以下设置器,您就有了一个本地化字段

<?php
namespace Wrwr;
class ObjectWithLocalization
{
    private $pizzas = [];

    public function setPizza(string $locale, string $preference)
    {
        $this->pizzas[$locale] = $preference;
    }

    public function getPizza(string $locale)
    {
        return $this->pizzas[$locale];
    }
}

这将生成支持本地化的名为'pizza'字段的设置器和获取器。

在Symfony框架中

如果您想在Symfony框架中使用它,您只需注册类Apie\ObjectAccessNormalizer\Normalizers\ApieObjectAccessNormalizer作为服务,并将其标记为'tagger.normalizer'以将其添加到symfony serializer。