linio/input

摘要:抽象HTTP请求输入处理,提供数据注入和验证的简单接口

2.9.1 2023-03-14 12:08 UTC

README

Latest Stable Version License Build Status Scrutinizer Code Quality

Linio Input是Linio框架的另一个组件。它旨在抽象HTTP请求输入处理,允许与您的领域模型无缝集成。该组件负责:

  • 解析请求体内容
  • 验证输入数据
  • 将输入数据注入到对象中

安装

安装Linio Input的推荐方式是通过composer

{
    "require": {
        "linio/input": "dev-master"
    }
}

测试

要运行测试套件,您需要通过composer安装依赖项,然后运行PHPUnit。

$ composer install
$ phpunit

使用

这个库非常容易使用:首先,您需要创建您的输入处理类。输入处理类负责指定从请求中期望接收哪些数据。让我们创建一个

<?php

namespace Linio\Api\Handler;

use Linio\Component\Input\InputHandler;

class RegistrationHandler extends InputHandler
{
    public function define()
    {
        $this->add('referrer', 'string');
        $this->add('registration_date', 'datetime');

        $user = $this->add('user', 'Linio\Model\User');
        $user->add('name', 'string');
        $user->add('email', 'string');
        $user->add('age', 'integer');
    }
}

现在,在您的控制器中,您只需要将数据绑定到处理程序

<?php

namespace Linio\Api\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class RegistrationController
{
    public function registerAction(Request $request): Response
    {
        $input = new RegistrationHandler();
        $input->bind($request->request->all());

        if (!$input->isValid()) {
            return new Response($input->getErrorsAsString());
        }

        $data = $input->getData();
        $data['referrer']; // string
        $data['registration_date']; // \DateTime
        $data['user']; // Linio\Model\User

        return new Response(['message' => 'Valid!']);
    }
}

类型处理程序

当您正在定义输入处理程序的字段时,有一些类型可供选择:字符串、整数、布尔值、日期时间等。这些是库提供的预定义类型,但您也可以创建自己的类型。这种魔法是由Linio\Component\Input\TypeHandler处理的。TypeHandler允许您添加新类型,这些类型是BaseNode类的扩展。

<?php

class GuidNode extends BaseNode
{
    public function __construct()
    {
        $this->addConstraint(new Linio\Component\Input\Constraint\GuidValue());
    }
}

$typeHandler = new Linio\Component\Input\TypeHandler();
$typeHandler->addType('guid', GuidNode::class);

$input = new RegistrationHandler();
$input->setTypeHandler($typeHandler);

在这个例子中,我们创建了一个新的guid类型,它具有内置的约束来验证内容。您可以使用自定义类型来完成各种事情:添加预定义约束链、转换器、实例化器和自定义值的生成方式。

约束

Linio Input允许您对字段应用约束。这可以通过在输入处理程序的add()方法中提供第三个参数来完成

<?php

use Linio\Component\Input\Constraint\Pattern;

class RegistrationHandler extends InputHandler
{
    public function define()
    {
        $this->add('referrer', 'string', ['required' => true]);
        $this->add('registration_date', 'datetime');

        $user = $this->add('user', 'Linio\Model\User');
        $user->add('name', 'string');
        $user->add('email', 'string', ['constraints' => [new Pattern('/^\S+@\S+\.\S+$/')]]);
        $user->add('age', 'integer');
    }
}

该库默认包含几个约束

  • 枚举
  • GuidValue
  • NotNull
  • Pattern
  • StringSize

转换器

Linio Input允许您创建数据转换器,负责将简单的输入数据(如时间戳和唯一ID)转换为有意义的数据(如日期时间对象或完整实体(通过执行查询))。

<?php

namespace Linio\Api\Handler\Transformer;

use Doctrine\Common\Persistence\ObjectRepository;
use Linio\Component\Input\Transformer\TransformerInterface;

class IdTransformer implements TransformerInterface
{
    /**
     * @var ObjectRepository
     */
    protected $repository;

    public function transform($value)
    {
        try {
            $entity = $this->repository->find($value);
        } catch (\Exception $e) {
            return null;
        }

        return $entity;
    }

    public function setRepository(ObjectRepository $repository)
    {
        $this->repository = $repository;
    }
}

数据转换器可以在定义输入处理程序时按字段添加

<?php

use Linio\Api\Handler\Transformer\IdTransformer;

class RegistrationHandler extends InputHandler
{
    /**
     * @var IdTransformer
     */
    protected $idTransformer;

    public function define()
    {
        $this->add('store_id', 'string', ['transformer' => $this->idTransformer]);
    }

    public function setIdTransformer(IdTransformer $idTransformer)
    {
        $this->idTransformer = $idTransformer;
    }
}

实例化器

Linio Input允许您按字段使用不同的对象实例化器。这可以通过在输入处理程序的add()方法中提供第三个参数来实现

<?php

use Linio\Component\Input\Instantiator\ConstructInstantiator;
use Linio\Component\Input\Instantiator\ReflectionInstantiator;

class RegistrationHandler extends InputHandler
{
    public function define()
    {
        $this->add('foobar', 'My\Foo\Class', ['instantiator' => new ConstructInstantiator()]);
        $this->add('barfoo', 'My\Bar\Class', ['instantiator' => new ReflectionInstantiator()]);
    }
}

该库默认包含几个实例化器

  • ConstructInstantiator
  • PropertyInstantiator
  • SetInstantiator
  • ReflectionInstantiator

默认情况下,SetInstantiator由Object和Collection节点使用。

输入处理程序

Linio Input支持通过嵌套可移植、可重用的输入处理程序。这是通过在添加字段时将handler包含在选项参数中实现的。

假设您的应用程序处理邮寄地址

<?php

class OrderHandler extends InputHandler
{
    public function define()
    {
        $address = $this->add('shipping_address', Address::class);
        $address->add('street', 'string');
        $address->add('city', 'string');
        $address->add('state', 'string');
        $address->add('zip_code', 'integer');
    }
}

而不是在需要处理地址的地方重复,您可以提取地址到其自己的输入处理程序,并在整个应用程序中重用它。

<?php

class AddressHandler extends InputHandler
{
    public function define()
    {
        $address->add('street', 'string');
        $address->add('city', 'string');
        $address->add('state', 'string');
        $address->add('zip_code', 'integer');
    }
}

class OrderHandler extends InputHander
{
    public function define()
    {
        $this->add('shipping_address', Address::Class, ['handler' => new AddressHandler()]);
    }
}

class RegistrationHandler extends InputHander
{
    public function define()
    {
        $this->add('home_address', Address::Class, ['handler' => new AddressHandler()]);
    }
}