helixdigital-io/laravel-hyrule

Laravel构建验证规则的流畅API

v3.0.2 2024-03-13 10:08 UTC

This package is auto-updated.

Last update: 2024-09-13 11:09:54 UTC


README

Hyrule提供了一个面向对象的、流畅的API,用于构建Laravel验证组件的验证规则。这解锁了使定义一组规则以强制执行在API开发中典型的复杂、嵌套数据结构的模式。

为什么

在Laravel中定义验证规则涉及手动构建数组。随着业务逻辑的发展,验证规则变得更加复杂,这些数组会不断增长,构建它们也变得更加复杂。很快,你就会发现自己正在操作数组:根据条件添加或删除规则,重构可重用的段等。随着时间的推移,这种模式可能会变得非常笨拙。管理验证规则定义的感觉可能会失控。这个库旨在通过提供更好的API来解决这个问题,从而帮助您长期解决。

  • 流畅的API允许您以人体工程学的方式定义规则,例如轻松添加条件,不再需要进行错误易发的数组操作。
  • 可组合的:简化了可以重复多次、在多个嵌套级别上重用的规则构建逻辑。不再需要传递并重新构建点表示的前缀。
  • 严格性意味着更少惊喜:促进数据类型的强制执行,并默认拒绝未知字段。

安装

composer require square/laravel-hyrule:^2.0

为了支持PHP 7.4,请安装1.*版本。请参阅1.x README

设置

1.) 如果您没有启用包发现,您将需要手动注册服务提供者

// config/app.php

return [
    // ...
    'providers' => [
       // ...
       Square\Hyrule\HyruleServiceProvider::class,
       // etc.
     ],
];

2.) 发布配置

php artisan vendor:publish --provider="Square\Hyrule\HyruleServiceProvider"

使用服务提供者和默认配置将允许您的应用程序使用StrictValidator

API基础

初始化规则构建器并添加第一个字段

// Initialize a new builder: it will help you build up your validation rule-set.
$builder = Hyrule::create();

// Describe your expected input:
// It needs the field name *and* the data-type.
// This creates a *Node* that you can then attach rules to:
$builder->string('first_name')
    ->required() // Attach rules. This one marks the field as required.
    ->max(255); // ...and this one says it cannot be greater than 255 chars in length.

完善其他字段及其规则

$builder
    ->string('first_name')
        ->required()
        ->max(255)
        ->end() // Tell the builder you are done w/ this field...
    ->string('last_name') // ...so you can start a new one!
        ->required()
        ->max(255)
        ->end()
    ->integer('age') // ...This field is an integer.
        ->required()
        ->min(21)
        ->max(60)
        ->end();


$rules = $builder->build();

// $rules:
[
    '' => ['required', 'array:first_name,last_name,age'],
    'first_name' => ['string', 'required', 'max:255'],
    'last_name' => ['string', 'required', 'max:255'],
    'age' => ['integer', 'required', 'min:21', 'max:60'],
]

开始验证!

// Compile into an array Illuminate\Validation\Validator understands.
$rules = $builder->build();

// Use it e.g.
$validator = Validator::make($data, $rules);

// ...or
$request->validate($rules);

// etc.

字段API

Hyrule强制您为每个字段定义预期的数据类型。它支持所有类型的范围,从标量类型到非标量类型。

标量类型

添加标量字段就像这样简单

$builder->string('product_name');
$builder->integer('quantity');
$builder->float('rating');
$builder->numeric('display_price')
$builder->boolean('on_sale');

非标量类型

无论您的验证规则多么深入和复杂,您都可以使用相同的API集合。

对象

使用->object(...)开始定义嵌套字段,例如

$builder
    // "nutritional_facts" is a required field w/ a bunch of nested fields.
    ->object('nutritional_facts')
        ->required()
        // Describe the fields:
        ->integer('servings_per_container')
            ->required()
            ->min(1)
            ->end()
        ->string('serving_size')
            ->required()
            ->min(1)
            ->max(30)
            ->end()
        // "fat", a nested field, has a bunch of nested fields, too.
        ->object('fat')
            ->integer('saturated_fat_grams')->end()
            ->integer('saturated_fat_percent')
                ->max(100)
                ->end();
            ->end();
未知字段

默认情况下,Hyrule通过仅允许通过字段API显式定义的字段来帮助您构建健壮和安全的应用程序。这是专门设计来帮助您有意识地处理数据预期的。例如,这是您的API可以进一步清理用户输入的另一种机制。

如果您期望字段通过,则库仍要求您指定数据类型。但您不必指定其他规则

Hyrule::create()
    ->string('name')
      ->end()
    // etc.

如果您想允许未知字段通过,请在适当的节点上使用此方法

Hyrule::create()
  ->allowUnknownProperties() // <- Allows unknown fields at root-level.
  ->object('data')
    ->allowUnknownProperties() // <- It does not carry-over. Add it to everywhere you wish to skip this.
    // etc.

标量值的数组

正如您所猜到的:从->array()开始

// Defines an array field named "tags"...
$builder
    ->array('tags')
        // Array length must be between 1-10 elements long:
        ->min(1)
        ->max(10)
        // ...and each element (i.e. a tag) must be a string between 3-100 chars in length.
        ->each('string')
            ->min('3')
            ->max('100');
        // etc.

正如您在下面的示例中所看到的,Hyrule甚至对数组中的内容也促进了严格性。

对象的数组

就像定义任何其他数组字段一样定义它,并使用完全相同的API来定义嵌套字段

$builder
    // Required "skus" must be between 1-10 items.
    ->array('skus')
        ->required()
        ->min(1)
        ->max(10)
        // Each SKU in the array are objects of their own:
        ->each('object')            
            // Each SKU has these fields:
            ->string('name')
                ->required()
                ->max(255)
                ->end()
            ->integer('quantity')
                ->min(0)
                ->end()
            // etc.

文件上传

从2.3版本开始,Hyrule支持指定文件上传的规则

$builder
    ->file('attachment')
        ->required()
        ->mime('image', 'video', 'text')
        ->end()
    // etc.

请参阅以下详细指南,了解如何通过文件类型(MIME类型)、尺寸等验证文件上传。

规则API

首先让我们谈谈当您使用上述Fields API时会发生什么。当您定义一个字段时,构建器会创建并返回一个节点。然后您可以使用规则API在节点上添加验证规则。

基本示例
// Adding built-in validation rules in Laravel
$builder
    ->string('foobar') // Returns a `StringNode` for the "foobar" field.
    ->required() // Adds the "required" validation rule.
    // Supports rules that accepts parameters like:
    ->min(1) // Adds "min:1"
    ->max(255) // Adds "max:1"
    ->requiredIf('vehicle_type', 'car') // Adds "required_if:vehicle_type,car"

    // Supports rules that access multiple parameters like:
    ->in('A', 'B', 'C') // Adds "in:A,B,C"
    // etc.
自定义规则支持

此库帮助您构建验证规则定义,并且不会限制您使用Laravel之外的定制规则。

$builder
    ->string('foobar')
        // Converts camel-case to snake-case notation:
        ->barBaz('olives', 'on', 'pizza') // Adds "bar_baz:olives,on,pizza"

        // Supports raw rule definitions:
        ->rule('required_without:another_field')

        // ... as well as custom Rule objects:
        ->rule(new MyCustomRule());

->end()是什么意思?

一旦您了解Square\Hyrule\Builder管理一个节点树,并且Fields API返回子节点,您只需知道->end()返回节点的父节点,这是遍历树回溯的流畅方式。

$builder = Hyrule::create() // The root
    ->string('name')
        ->required()
        ->end() // Brings us back to $builder, the root node
        
    // New field on root:
    ->object('characteristics')
        ->required()
        ->string('eye_color')
            ->in(...EyeColors::all())
            ->end() // Back to "characteristics"
        ->numeric('height_cm')
            ->end() // Back to "characteristics"
        ->with(...)
    ->end() // Back to $builder, the root node.
    
    // Another field on root:
    ->array('siblings')
        ->max(10)
        ->each('object') // Starts the "*" ObjectNode
            ->string('name')
            ->end() // Back to the "*" ObjectNode
        ->end() // Back to "siblings"
    ->end() // Back to $builder, the root node.

    // etc.

如果您不喜欢这种方式,可以使用Fields-With API

高级主题