Laravel Rule::in 验证:如何检查值是否存在于动态数组中
在Laravel开发中,我们经常会遇到需要验证某个字段的值是否属于特定集合的场景,比如验证用户选择的分类ID是否存在于系统中已有的分类列表中。Laravel的验证规则Rule::in就是专门用来处理这类需求的,它支持传入静态数组,也支持动态的数组参数,非常灵活。
基础用法:静态数组验证
最基础的用法是直接传入一个固定的数组作为Rule::in的参数,验证字段值是否在这个数组中存在。
<?php
namespace AppHttpRequests;
use IlluminateFoundationHttpFormRequest;
use IlluminateValidationRule;
class ArticleRequest extends FormRequest
{
public function rules()
{
return [
'status' => [
'required',
Rule::in(['draft', 'published', 'archived']),
],
];
}
}上面的例子中,我们验证status字段的值只能是draft、published、archived三者之一,如果传入其他值,验证会失败并返回对应错误提示。
动态数组验证:从数据库或业务中获取数组
实际开发中,我们更多需要验证的值是动态的,比如要验证的分类ID必须存在于当前租户的有效分类列表中,或者验证用户角色必须在系统已有的角色集合里。这时候只需要把动态生成的数组传入Rule::in即可。
场景1:从数据库查询获取动态数组
假设我们有一个categories表,存储了所有可用的分类,现在要验证提交的category_id是否存在于表中:
<?php
namespace AppHttpRequests;
use IlluminateFoundationHttpFormRequest;
use IlluminateValidationRule;
use AppModelsCategory;
class ProductRequest extends FormRequest
{
public function rules()
{
// 动态获取所有有效分类的ID数组
$validCategoryIds = Category::where('is_active', 1)->pluck('id')->toArray();
return [
'category_id' => [
'required',
'integer',
Rule::in($validCategoryIds),
],
];
}
}这里首先通过查询获取所有激活状态的分类ID,转成数组后传给Rule::in,验证时会检查提交的category_id是否在这个动态数组中。
场景2:结合当前请求参数生成动态数组
有时候动态数组需要依赖其他请求参数生成,比如验证用户选择的关联ID必须属于当前用户自己创建的资源:
<?php
namespace AppHttpRequests;
use IlluminateFoundationHttpFormRequest;
use IlluminateValidationRule;
use AppModelsOrder;
class RefundRequest extends FormRequest
{
public function rules()
{
// 获取当前用户的所有可退款订单ID
$validOrderIds = Order::where('user_id', $this->user()->id)
->whereIn('status', ['paid', 'shipped'])
->pluck('id')
->toArray();
return [
'order_id' => [
'required',
'integer',
Rule::in($validOrderIds),
],
'refund_reason' => 'required|string|max:200',
];
}
}注意事项
Rule::in的参数是数组,如果传入空数组,所有值都会验证失败,所以生成动态数组时要确保数组不为空,或者额外添加存在性判断。动态数组的元素类型要和验证字段的类型一致,比如字段是整型的
category_id,数组里的元素也应该是整型,避免出现字符串和整型比较导致的验证异常。如果动态数组数据量很大,频繁查询可能影响性能,可以考虑添加缓存,比如把分类ID数组缓存一段时间,减少数据库查询次数。
自定义错误提示
默认的Rule::in错误提示是“选择的字段值无效”,如果我们需要更友好的提示,可以在验证请求的messages方法中自定义:
<?php
namespace AppHttpRequests;
use IlluminateFoundationHttpFormRequest;
use IlluminateValidationRule;
use AppModelsCategory;
class ProductRequest extends FormRequest
{
public function rules()
{
$validCategoryIds = Category::where('is_active', 1)->pluck('id')->toArray();
return [
'category_id' => [
'required',
'integer',
Rule::in($validCategoryIds),
],
];
}
public function messages()
{
return [
'category_id.in' => '请选择有效的商品分类',
];
}
}通过以上方式,我们就可以灵活使用Rule::in完成各种动态数组的验证需求,既支持静态固定值,也支持从数据库或业务中动态生成验证集合,满足不同场景的验证要求。