somnambulist/form-request-bundle

为Symfony添加类似Laravel的表单请求;基于adamsafr/form-request-bundle

2.1.2 2024-06-12 23:32 UTC

This package is auto-updated.

Last update: 2024-09-13 00:12:15 UTC


README

GitHub Actions Build Status Issues License PHP Version Current Version

基于Adam Sapraliev的原始工作,为Symfony实现Laravel表单请求的版本。

需求

  • PHP 8.0+
  • symfony/framework-bundle

安装

使用composer安装,或从github.com检查/拉取文件。

  • composer require somnambulist/form-request-bundle

用法

SomnambulistFormRequestBundle添加到你的bundles.php列表中,并添加一个配置文件到packages中(如果需要配置捆绑包)。以下选项可以设置

somnambulist_form_request:
    subscribers:
        authorization: true
        form_validation: true

authorization注册一个事件订阅者,将AccessDeniedExceptions转换为JSON响应。form_validation注册一个事件订阅者,将FormValidationException转换为JSON响应,包括失败的验证字段、规则和消息。

注意:订阅者默认启用。

自定义规则

此包包括以下规则的覆盖

  • required - 验证字段是必需的,支持SymfonyUploadedFile文件
  • uploaded_file - 验证上传文件,支持SymfonyUploadedFile文件
  • mimes - 验证上传文件MIME类型是给定扩展之一

属性透传

以下ParameterBag可以通过属性访问器或方法调用访问

  • attributes
  • cookies
  • files
  • headers
  • query
  • request
  • server

此外,以下属性也可用

  • content
  • session

创建表单请求

要创建表单请求,扩展基类Somnambulist\Bundles\FormRequestBundle\Http\FormRequest并重写rules()方法以添加自己的验证规则。rules方法通过source属性访问当前请求,因此可以使用请求信息来构建规则。

验证规则使用somnambulist/validation而不是Symfony的验证组件,以便更容易设置和扩展。

例如:要创建一个专门用于验证创建新用户数据的表单请求,可以创建以下内容

<?php
use Somnambulist\Bundles\FormRequestBundle\Http\FormRequest;

class NewUserFormRequest extends FormRequest
{
    public function rules() : array
    {
        return [
            'name'     => 'required|min:8|max:100',
            'email'    => 'required|min:4|max:255|email',
            'password' => 'required|min:8|max:100',
        ];
    }
}

验证后的数据存储在data属性中,可以直接从控制器中访问。从版本1.5.0开始,这是一个ValidatedDataBag,之前是ParameterBag。数据包支持点符号访问键(具有与主FormRequest相同的限制),以及nullOrValue和针对键、值以及通过回调过滤的几个其他方法。

或者:可以通过属性透传或通过调用source()来访问原始请求数据,以获取请求对象。

使用表单请求

在你的控制器中,不要对标准请求进行类型提示,而是对表单请求进行类型提示。如果验证成功,则请求中的数据将适合控制器使用。

例如

<?php
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class CreateUserController extends AbstractController
{
    public function __invoke(NewUserFormRequest $form)
    {
        // handle request
        $form->data()->get('name');
    }
}

FormRequest 支持点符号访问以获取嵌套值。这可以用于获取单个值、轻松检查深层嵌套值或将一组值提取到值对象或集合中。

例如:要获取单个值:$form->get('user.address.line_1') 将从包含地址数组的用户数组中获取 line_1

点符号的行为有几个边缘情况

  • 目前不支持 * 运算符
  • only 将返回一个扁平化的 ParameterBag,其中包含点符号键
  • without 将返回一个包含原始数据的 ParameterBag,但不包含指定的键

此外

当使用 only 与点符号时,结果将与 nullOrValue 类似,但 subNull 为 false,它可能包含来自请求、查询或文件中的值。如果需要精细控制,请使用 nullOrValue

当使用 without 与点符号时,结果将包含来自请求、查询和文件的数据。由于返回的是一个 ParameterBag,因此没有点访问器。

可选

如果您使用 api-bundle 并文档化不应视为验证数据一部分的查询参数(例如页面/每页等);可以通过覆盖 $ignore 属性并使用应从验证数据中排除的键名集合来排除这些参数。

授权 Form 请求

Form 请求可以具有自定义授权检查;然而,此功能需要实现 Symfony Security,因为需要 security 服务。

要添加自定义授权检查,覆盖 authorize() 方法并添加必要的检查。

authorize 方法接收当前 Security 服务,该服务可以访问当前用户和 isGranted() 方法。

例如,要要求新用户只能由管理员用户创建

use Somnambulist\Bundles\FormRequestBundle\Http\FormRequest;
use Symfony\Component\Security\Core\Security;

class NewUserFormRequest extends FormRequest
{
    public function authorize(Security $security) : bool
    {
        return $security->isGranted('ROLE_ADMIN');
    }

    public function rules() : array
    {
        return [
            'name'     => 'required|min:8|max:100',
            'email'    => 'required|min:4|max:255|email',
            'password' => 'required|min:8|max:100',
        ];
    }
}

添加验证规则

可以通过创建一个新的扩展 Somnambulist\Components\Validation\Rule 的规则来添加自定义验证器,实现验证逻辑(以及任何自定义消息),然后创建一个新的服务。规则将自动使用类名(不包含命名空间)转换为 snake_case 的形式分配给验证器。或者,可以将单个规则标记为 somnambulist.form_request_bundle.rule 并使用 rule_name 属性设置规则的特定别名

例如

<?php
use Somnambulist\Components\Validation\Rule;
use Ramsey\Uuid\Uuid;

class UuidRule extends Rule
{
    protected string $message = 'The :attribute is not a valid UUID or is NIL';

    public function check($value): bool
    {
        return Uuid::isValid($value) && $value !== Uuid::NIL;
    }
}
services:
    App\Rules\UuidRule:
        tags:
            - { name: 'somnambulist.form_request_bundle.rule', rule_name: 'uuid' }

如果没有标记,此规则将注册为:uuid_rule

由于规则被注册为服务,因此您可以使用其他服务进行数据库或 API 检查等。

有关如何传递参数、可用规则以及如何处理消息翻译的详细信息,请参阅 文档

注意:所有规则都必须具有唯一名称,相同的名称将覆盖任何现有规则。

注意:需要一些规则来内部使用;如果您遇到奇怪的行为,可能是因为您更改了内置规则的行为。

添加缺少的 MIME 类型

somnambulist/validation 包含一个默认注册并可作为服务使用的 MIME 类型猜测器。您可以通过注入该服务并对其进行配置来添加额外的 MIME 类型和扩展,无论是在启动方法中还是在服务中。

或者:可以实现 MimeTypeGuesser 接口以完全替换实现。

测试

使用 vendor/bin/phpunit 运行 PHPUnit 9+ 测试。