lphilippo / laravel-castable-form-request
Laravel/Lumen 包,用于为表单请求添加 Eloquent 类型的转换。
Requires
- php: >= 7.4
- illuminate/http: >= 8.0
- illuminate/support: >= 8.0
- illuminate/validation: >= 8.0
Requires (Dev)
- laravel/framework: >= 8.0
- phpunit/phpunit: >= 9.0
This package is auto-updated.
Last update: 2024-09-19 11:20:59 UTC
README
首先,您现在可以在 Lumen 中使用类似于 Laravel 的表单请求。此外,您还可以通过默认值和(嵌套!)转换扩展您的 FormRequests,以完全控制进入应用程序的数据。需要注意的是,对于嵌套数组,每个属性都需要验证规则,否则属性将不会包含在清洗后的结果中。
在验证之前,将 defaults()
与请求的数据源合并,而 casts()
在验证成功后应用。通过强制执行此顺序,可以使用转换来控制数据提供给应用程序的类型,无论用户数据的验证如何。这对于内部使用 Carbon
日期特别有用。
与 Laravel 中表单请求的标准实现类似,没有区分请求的各个输入源。
安装
composer require lphilippo/laravel-castable-form-request
Lumen 的配置
要在 Lumen 中使用表单请求,您只需要在 bootstrap/app.php
中注册服务提供器。
$app->register(LPhilippo\CastableFormRequest\ServiceProvider::class);
Lumen 中的使用
简单地从 LPhilippo\CastableFormRequest\Http\Requests\LumenFormRequest
扩展您自己的表单请求,并添加所需的规则、转换和默认值。
Laravel 中的使用
由于本包的 FormRequest
不应替代 Laravel 的标准 FormRequest
(除非您不需要重定向操作),所有功能仍可以通过稍微多一点的代码实现。
FormRequest
仅扩展基本类并添加了 LPhilippo\CastableFormRequest\Casting\CastsWhenValidatedTrait
。这将允许应用 casts()
,但为了使用 defaults()
,请将以下代码添加到您的类中
/** * Allow default values through filtering before validation. * * @return array */ public function prepareForValidation() { return $this->replace( array_merge( $this->defaults(), $this->all() ) ); }
完整的 FormRequest 示例
以下是一个完整示例,它使用同一实现中的验证、转换和默认值
use LPhilippo\CastableFormRequest\Http\Requests\FormRequest; class ProductRequest extends FormRequest { /** * @inheritdoc */ public function defaults() { return [ 'id' => 1, ]; } /** * @inheritdoc */ public function rules() { return [ 'created_at' => 'required|date_format:Y-m-d', 'id' => 'required|integer', ]; } /** * @inheritdoc */ public function casts() { return [ 'created_at' => 'datetime', 'id' => 'integer', ]; } }
在您的控制器中,您可以访问验证过的未转换数据
$request->validated();
或者完全清洗后的数据,这为后续的内部处理做好了准备。
$request->sanitised();
请注意,sanitised
不包括未验证的属性。这也适用于嵌套数组,将剥离未验证的属性。
嵌套验证规则
类似于标准验证规则,转换规则也可以嵌套。例如,以下规则是有效的。请注意,转换规则应始终与验证规则(首先应用)一起工作,否则转换的结果可能不可预期。
/** * @inheritdoc */ public function casts() { return [ 'products' => 'array', 'products.*' => 'array', 'products.*.id' => 'int', 'products.*.category_id' => 'array', 'products.*.category_id.*' => 'int', }
虽然可以通过仅定义点表示法来缩短此处的写法,因为数组规则将隐含存在
/** * @inheritdoc */ public function casts() { return [ 'products.*.id' => 'int', 'products.*.category_id.*' => 'int', }
嵌套默认值
可以应用相同的嵌套方法来处理默认值。然而,需要指出的是,只有当结果 validated
内容中包含数组时,才会应用嵌套数组默认值。它不会初始化数组本身。
/** * @inheritdoc */ public function casts() { return [ 'status' => 'pending', 'products.*.status' => 'available', 'provider.country.currency' => 'EUR', }
添加自定义验证规则
在某些情况下,指定 $rules
变量中的所有验证规则是不够的。例如,如果基于请求路由需要更定制的验证,可以通过添加以下结构来实现
/** * @inheritdoc */ public function withValidator($validator) { $entityId = $this->route('id'); if ($entityId === 1) { $validator->addRules([ 'key' => 'required|string|in:' . implode(',', self::RESTRICTED_KEYS), ]); } }
重要限制(设计目的)
由于本包的主要目的是验证进入系统的任何输入,验证规则始终优先。不幸的是,当你在数组上指定任何验证规则(按照Laravel的标准行为),在调用Validator::validated
时,数组的元素将不再被过滤。
由于这与我们的目的相悖,该功能被禁用,这允许我们定义每个数组元素。缺点是,原始数据中可能存在的空数组将不会出现在sanitised
的结果中。
虽然可能实现,但目前并未考虑在内。