nikita2206/symfony-request-converter

此包已被废弃且不再维护。未建议替代包。

请求转换器将请求数据转换为数据对象

dev-master 2016-09-09 13:55 UTC

This package is not auto-updated.

Last update: 2023-06-10 12:06:08 UTC


README

Build Status Coverage Status

将API请求从纯PHP数组转换为请求对象。

示例

在您的控制器操作中,您可以使用

public function addBlogPostAction(PostRequest $post)
{
    $this->commandBus->execute(new NewPost($post));
}

请求将自动从纯数组形式转换为PostRequest类实例(不调用构造函数创建)并进行验证

use RequestConverter\Annotation\Type;
use RequestConverter\Annotation\Optional;
use RequestConverter\Annotation\Request;

/**
 * We need to use this annotation in order to tell request converter that it should pick up action
 *   parameter type-hinted with this class
 * @Request()
 **/
class PostRequest
{
    /**
     * @Type("string")
     **/
    private $title;
    
    /**
     * @Type("string")
     **/
    private $text;
    
    /**
     * @Type("string")
     * @Optional()
     **/
    private $author;
}

如何设置

在您的composer.json中引入nikita2206/symfony-request-converter之后,您需要注册异常监听器以渲染RequestConverter\Exception\BadRequestException,如果请求无效则将抛出此异常。

这是该监听器的基本示例,您当然希望使其符合您的API错误规范。或者,作为一个更好的解决方案,可以将错误渲染委托给另一个控制器,就像在Symfony\Component\HttpKernel\EventListener\ExceptionListener中做的那样。

use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use RequestConverter\Exception as Ex;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;

class ExceptionListener
{
    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        if ( ! $event->getException() instanceof Ex\BadRequestException) {
            return;
        }

        $errors = [];

        // this exception is thrown when there was a problem while mapping input data on the object:
        //   * missing field
        //   * incompatible type (string when array is expected f.e.)
        //   * uncoercible value (string "45zz" when integer is expected)
        if ($event->getException() instanceof Ex\RequestConversionException) {
            foreach ($event->getException()->getErrors() as $err) {
               $errors[] = ["field" => $err->getField(), "kind" => get_class($err)];
            }

        // this exception is the result of symfony/validation component, it has ConstraintViolationListInterface
        } elseif ($event->getException() instanceof Ex\RequestValidationException) {
            foreach ($event->getException()->getViolations() as $v) {
                $errors[] = ["field" => $v->getPropertyPath(), "kind" => $v->getMessage()];
            }
        }

        $event->setResponse(new Response(\json_encode($errors), 400));
    }
}

如何使用

所有根请求类都需要标记为RequestConverter\Annotation\Request注解。并且该请求类中的每个成员都可以标记为RequestConverter\Annotation\Type注解,以强制将其转换为该类型。下面是所有可能类型的参考。您还可以使用RequestConverter\Annotation\Optional注解来忽略请求有效载荷中字段的缺失。

默认情况下,RequestConverter将使用请求体,但您可以将它切换为使用查询来获取某些操作参数。为此,您需要使用Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter注解并使用options={"query"=true}参数,如下所示

/**
 * @ParamConverter("filter", options={"query"=true})
 */
public function filterPostsAction(Filter $filter)
{

}

类型注解

您可以使用几种类型,这些类型包括:int、bool、float、string、array、map以及类名。如果传入的数据不是正确的类型,我们将尝试将其转换,以下是一个可能的类型列表及其与其他类型的转换兼容性。

Int类型

除了int外,它还可以接受表示整数的数值string。否则,如果它是文本字符串或表示浮点数,您将获得UncoercibleValueError

Bool类型

也可以接受intfloatstring。对于intfloat以及数值字符串,将产生false(对于0)和true(对于所有其他数字)。对于非数值字符串,它将首先尝试将它们与预设值[yes, true, Y, T][no, false, N, F]进行比较,如果未找到匹配项,它将静默地将字符串转换为(bool)$value

浮点类型

也可以接受 intstring。如果字符串表示浮点数或整数,则尝试将字符串强制转换为 float

字符串类型

接受 stringintfloat,并将其转换为 string

数组类型

仅接受数组。

此类型是参数化的:对于 T 的数组,可以使用 array<T> 语法(类似于流行语言中的泛型语法)。如果 T 是类名,它将被映射和验证。

映射类型

仅接受数组。

此类型是参数化的,有两个重载:Map<V>Map<K, V>。类型参数 K 只能是 stringint

类名类型

如果你在 RequestConverter\Annotation\Type 注解中使用自己的类名或将其作为 arrayMap 类型的参数,RequestConverter 将尝试将输入数据映射到该类的新创建的对象。

验证

你还可以使用 symfony/validator 组件的验证约束。如果没有错误,则应用验证器,默认为验证组。

扩展 RequestConverter

你可以添加自己的数据类型,用于与 Type 注解和参数化类型一起使用 - 为此,你需要创建一个 RequestConverter\Coercion\TypeCoercer 接口的新实现,并在 RequestConverter\Coercer 服务中注册它。目前此服务不可配置,因此你必须使用 Symfony DI 的服务定义覆盖功能,覆盖 request_converter.coercer 服务的定义。

贡献

欢迎所有类型的贡献:文档、代码或测试。项目主要遵循 PSR-2 风格指南。

你可以从项目的根目录运行测试,使用 ./vendor/bin/phpunit 命令。