本文目录导读:

- Laravel 内置验证(最推荐、最常用)
- spatie/laravel-validation-rules(Spatie 规则扩展)
- arcanedev/sanitizer 或 waavi/sanitizer (数据清洗/过滤)
- laravel-request-docs / 自定义验证类(API 文档驱动)
- 场景决策速查表
- 终极建议
这是一个很实用的问题,在Laravel生态中,验证包的选择主要取决于你的项目需求(比如是否需要明显的API验证、是否需要复杂的规则复用、是否倾向于使用表单请求等方式)。
目前主流的选择主要有以下几种,你可以根据场景来决策:
Laravel 内置验证(最推荐、最常用)
适用场景: 绝大多数常规Web应用、API、新手项目、团队标准化项目。
推荐理由:
- 零依赖: 框架自带,无需额外安装。
- 功能完整:
- 支持
Form Request(表单请求验证):这是最优雅的方式,将验证逻辑抽离到独立的类中。 - 支持
Validator::make()手动验证:灵活性极高。 - 规则丰富:
required、unique、exists、email、regex、日期、大小等应有尽有。 - 支持
Rule对象:Laravel 8+ 提供了更优雅的规则定制方式。 - 自定义规则:通过
Rule::custom()或创建Rule类。
- 支持
- 社区标准: 绝大多数 Laravel 教程、包、团队都以此为基础。
- 错误消息处理: 内置多语言支持,错误消息可以直接在语言文件中定义。
代码示意(Form Request):
// 1. 创建: php artisan make:request StorePostRequest
// 2. 定义规则:
public function rules(): array
{
return [
'title' => 'required|string|max:255|unique:posts,title',
'content' => 'required|string|min:10',
'author_email' => 'required|email:rfc,dns',
'tags' => 'array',
'tags.*' => 'exists:tags,id',
];
}
// 3. 在控制器中使用:
public function store(StorePostRequest $request) {
// 验证通过,直接使用 $request->validated() 获取数据
$validated = $request->validated();
}
缺点: 对于非常复杂的嵌套数组验证(如 items.*.price 需要相互依赖验证),规则定义会变得冗长。
spatie/laravel-validation-rules(Spatie 规则扩展)
适用场景: 当你需要大量常用但重复的验证规则(如手机号、IP地址、UUID、货币、域名等)。
推荐理由:
- 减少样板代码: 内置了超过40种常用规则,如
PhoneNumber、CountryCode、Currency、Domain、Password(复杂密码组合)等。 - 可读性强: 使用类名作为规则,比写正则表达式清晰得多。
- 可组合: 可以轻松与内置规则组合使用。
示例:
use Spatie\ValidationRules\Rules\PhoneNumber;
use Spatie\ValidationRules\Rules\Password;
$rules = [
'phone' => ['required', new PhoneNumber()],
'password' => ['required', new Password(8)->minLowercase(2)->minUppercase(1)->minNumeric(1)],
];
缺点: 不是核心功能,需要 composer require spatie/laravel-validation-rules,可能会增加少量依赖。
arcanedev/sanitizer 或 waavi/sanitizer (数据清洗/过滤)
适用场景: 在验证之前需要对输入数据进行格式化(如去除空格、转换为整数、HTML转义等)。
推荐理由:
- 预处理: 验证之前先清洗数据,可以避免因为空格导致验证失败(如
trim)。 - 类型统一: 将字符串数字转为真正的数字,便于后续验证(如
integer规则无法作用于字符串"123"吗?实际上可以,但清洗后更干净)。 - 完整流程: 清洗 -> 验证 -> 处理。
注意: Laravel 8+ 的内置 Str::of($value)->trim() 或中间件 TrimStrings 已经解决了一部分问题,但对复杂清洗需求仍有用。
laravel-request-docs / 自定义验证类(API 文档驱动)
适用场景: 团队需要将验证规则自动生成API文档(如 Swagger/OpenAPI)。
推荐理由:
- 如果你的项目使用
knuckleswtf/scribe或darkaonline/l5-swagger生成文档,通常它们会分析Form Request的定义,从而自动提取规则和描述。 - 结合
@return array的rules()方法,文档工具能自动生成参数表。
缺点: 这不是一个单独的验证包,而是与文档生成工具配合的方式。
场景决策速查表
| 你的需求 | 推荐方案 | 原因 |
|---|---|---|
| 普通CRUD + Web/API | Laravel 内置 Form Request |
最简单、最标准化、足够用 |
| 需要大量重复的复杂规则(如支付、物流) | Laravel 内置 + spatie/laravel-validation-rules |
节省代码量,规则清晰 |
| 需要强类型验证 / 复杂嵌套数组 | Laravel 内置 + 编写自定义 Rule 类 | 内置规则可嵌套,自定义类复用 |
| 需要验证前清洗数据 | 内置 TrimStrings + 手动 str_replace 或使用 waavi/sanitizer |
看需求轻重,轻量用内置,重度用包 |
| 极简主义 / 不想学复杂 API | 就只用手动 Validator::make() |
最简单,不需要创建文件 |
| API 需要多语言验证消息 | 内置验证(语言包在 resources/lang) |
支持多语言,国际化友好 |
| 需要 JSON Schema 验证 | justinrainbow/json-schema |
不常用,除非对接外部标准JSON Schema |
终极建议
对于90%的项目,直接使用 Laravel 内置的验证(Form Request)就够了。 这个是最稳妥、最流行、维护成本最低的方案。
如果你的项目特别复杂(如电商多层级 SKU 验证、支付表单海量规则),再考虑引入 spatie/laravel-validation-rules。
尽量不要自己造轮子(比如自己写大量的正则验证),因为 Laravel 内置的 unique:table,column 和 exists:table,column 已经非常强大。
一句话总结: 用 php artisan make:request 创建 Form Request,在里面写 rules() 和 messages(),这几乎是 Laravel 社区的“标准做法”。