earc/parameter-transformer

eArc - 显式架构框架 - 参数转换组件

0.0.1 2021-05-24 15:11 UTC

This package is auto-updated.

Last update: 2024-09-24 22:35:33 UTC


README

轻量级参数转换组件。使用类型提示来自动连接 对象函数方法

目录

安装

$ composer require earc/parameter-transformer

引导

earc/parameter-transformer 使用 earc/di 进行依赖注入和标记。

use eArc\DI\DI;

DI::init();

基本用法

earc/parameter-transformer 的所有转换功能都捆绑到服务 ParameterTransformer 中。参数转换器公开了五个方法

  • objectTransform(通过调用设置器并将值添加到输入中的属性来转换 对象
  • callableTransform(从输入生成一个数组,该 可调用 可以用这些参数调用)
  • callFromTransform(快捷函数:使用通过 callableTransform 提供的参数调用 可调用函数
  • constructFromTransform(快捷函数:使用通过 callableTransform 提供的构造函数参数实例化对象)
  • castFromTransform(快捷函数:通过 constructFromTransform 获取对象,并对其调用 objectTransform

所有方法都接受三个参数

  • 目标(从该目标读取类型提示并应用转换)
  • 输入 数组(从该输入计算类型提示参数的输入 - 如果 null,则从 php://input 中获取输入)
  • 配置 Configuration(一个配置对象,用于微调转换 - 如果 null,则使用默认配置)

自动连接函数和方法

use eArc\ParameterTransformer\Configuration;
use eArc\ParameterTransformer\ParameterTransformer;

$input = [
    'parameterNameOne' => 'someValue',
    'parameterNameTwo' => 'anotherValue',
    //...
];

// $target has to be a callable a class string or an instance of \ReflectionFunctionAbstract
$target = [MyClass::class, 'myMethod'];

$argv = (new ParameterTransformer())->callableTransform($target, $input, new Configuration());

自动更新对象

use eArc\ParameterTransformer\Configuration;
use eArc\ParameterTransformer\ParameterTransformer;

$input = [
    'parameterNameOne' => 'someValue',
    'parameterNameTwo' => 'anotherValue',
    //...
];

$target = new MyClass();

$target = (new ParameterTransformer())->objectTransform($target, $input, new Configuration());

配置和扩展转换

转换通过 Configuration 对象进行配置,并通过 ParameterTransformerFactoryInterfaceParameterTransformerFactoryServiceInterface 进行扩展。要正确使用它,您必须了解转换过程是如何工作的。

如何确定输入数组

如果通过第二个服务方法参数提供了输入数组,则使用该输入。否则使用 php://input 创建输入数组。

您可以通过 setDefaultResource() 方法提供替代回退

use eArc\ParameterTransformer\Configuration;

$config = (new Configuration())->setDefaultResource([new MyInputProvider(), 'getDefault']);

如何选择输入值

  1. 变量名称用于从输入中检索起始值。例如,如果变量名为 $product,则将 $input['product'] 作为值。

您可以通过 setMapping() 方法配置此行为

use eArc\ParameterTransformer\Configuration;

$mapping = [
    'id' => 0,
    'product' => 'productName',
    'description' => 'text',
];

$config = (new Configuration())->setMapping($mapping);

映射在选择输入值之前应用于键

  1. 如果键不存在,则使用下一个位置键(int
  2. 如果既不存在命名键也不存在下一个位置键,则抛出 NoInputException 异常

您可以通过 setNoInputIsAllowed() 方法更改此行为

use eArc\ParameterTransformer\Configuration;

$config = (new Configuration())->setNoInputIsAllowed(true);

而不是抛出异常,使用 null 值。

如何转换类型提示

  1. 如果 null 是类型提示,并且起始值是字符串 'null',则起始值将被视为 null
  2. 对于内置原始类型,如果起始值不是 null,则将其转换为结果值。
  3. 如果不是内置原始类型并且存在预定义的类型提示值,则使用预定义的类型提示值作为结果值。

您可以通过setPredefinedTypeHints()方法设置预定义的类型提示值。

use eArc\ParameterTransformer\Configuration;

$config = (new Configuration())->setPredefinedTypeHints([
    MyServiceOne::class => new MyServiceOne(),
    MyServiceTwo::class => new MyServiceTwo(),
    //...
]);

如果您想提供一个完整的Service-Container来增强此库,以您的依赖注入系统的力量,应使用ParameterTransformerFactoryServiceInterface来提供动态解决方案(见5)。

  1. 如果类型提示的类实现了ParameterTransformerFactoryInterface,则使用buildFromParameter()方法来构建结果值。

如果您有一种通过单个参数构建或检索对象的方法,例如实体,则可以实现此功能。

use eArc\ParameterTransformer\Interfaces\ParameterTransformerFactoryInterface;

class MyClient implements ParameterTransformerFactoryInterface
{
    //...

    public function __construct(string $connectionConfigurationString)
    {
        //...
    }

    //...

    public static function buildFromParameter($parameter) : static
    {
        return new MyClient((string) $parameter);
    }
}
  1. 对于所有实现ParameterTransformerFactoryServiceInterface并被其标记的服务,将调用buildFromParameter()直到其中一个返回一个对象。此对象用作结果值。

这对于实体特别有用。

use eArc\Data\Entity\Interfaces\EntityInterface;
use eArc\ParameterTransformer\Interfaces\ParameterTransformerFactoryServiceInterface;

class MyEntityTypeHintingService implements ParameterTransformerFactoryServiceInterface
{
    public function buildFromParameter(string $fQCN, $parameter) : object|null
    {
        if (is_subclass_of($fQCN, EntityInterface::class)) {
            return data_load($fQCN, $parameter);
        }
        
        return di_get(EntityManagerInterface::class)
            ->getRepository($fQCN)
            ?->find($parameter);
    }
}

di_tag(ParameterTransformerFactoryServiceInterface::class, MyEntityTypeHintingService::class);
  1. 如果类型提示的类可以通过earc/di构建,则将di_get()的结果作为结果值。

  2. 如果是一个联合类型,则依次取类型提示进行评估(1.-6)。第一个与输入值不同的结果(!=)且不为null的是结果值。

  3. 如果结果值为null且存在默认值提示,则默认值是新的结果值。

  4. 如果结果是null值,但类型提示不允许null,则抛出NullValueException

您可以通过setNullIsAllowed()方法禁用此行为。

use eArc\ParameterTransformer\Configuration;

$config = (new Configuration())->setNullIsAllowed(true);
  1. 转换后的输入值将从输入数组中删除。

如何转换可调用和函数

  1. 如果目标是类字符串,则检索构造函数方法。
  2. 对于参数及其类型提示,应用type hint transformation
  3. 结果作为按顺序的数组返回,其中参数名称作为键。

如何转换对象

与可调用和函数不同,没有结果数组。转换直接应用于对象。

  1. 首先处理方法,然后处理属性。

您可以通过setMethodsFirst()方法更改此行为。

use eArc\ParameterTransformer\Configuration;

$config = (new Configuration())->setMethodsFirst(false);
  1. 处理所有恰好有一个参数的公共方法,直到处理完整个输入数组。

您可以通过setFilterMethodssetMaxParameterCountsetNoInputIsAllowed方法更改此行为。

use eArc\ParameterTransformer\Configuration;

$config = (new Configuration())
    ->setFilterMethods(ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED)
    ->setMaxParameterCount(3)
    ->setNoInputIsAllowed(true);

如果最大参数数大于一个,则按参数数量顺序处理方法。

要仅使用属性转换,将最大参数数设置为零。

如果输入数组为空且不允许输入,则使用null值作为输入。

  1. 如果没有抛出异常,则使用结果数组调用方法。

  2. 对于每个公共属性,将评估类型提示,直到处理完整个输入数组。当前值将被替换为结果值。

您可以通过setFilterPropertiessetUsePropertyTransformation方法更改此行为。

use eArc\ParameterTransformer\Configuration;

$config = (new Configuration())
    ->setFilterProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED);

$config = (new Configuration())
    ->setUsePropertyTransformation(false);

附加信息

没有实现递归。通过earc/parameter-transformer构建类型提示的类必须显式完成。输入数据可以包含复杂的数据结构,因此如果已知对象结构,预处理是一个选项。

使用earc/cast将数据从输入数组映射到任意对象可以更高效,如果可以不考虑类型提示而只考虑属性名称完成。

版本

版本 0.0

  • 首次官方发布
  • PHP ^8.0
  • 支持的类型提示
    • 原生
      • null
      • int
      • float
      • bool
      • string
    • self
      • ParameterTransformerFactoryInterface
    • extern
      • 所有可以通过earc/di包中的di_get()函数构建的类
  • 类型提示转换可以通过ParameterTransformerFactoryServiceInterface进行扩展,以定义您自己的类类型提示转换