自定义数组验证规则StoreTicketTypeQuantity的实现需求
解决Laravel中票型购买数量的自定义验证规则问题
针对你提到的场景——用户提交多种票型的购买数量,需要验证每种数量是否符合TicketType表中对应票型的minPerUser和maxPerUser限制,我来一步步教你实现StoreTicketTypeQuantity这个自定义验证规则:
1. 生成自定义验证规则类
首先用Artisan命令快速生成规则文件:
php artisan make:rule StoreTicketTypeQuantity
这会在app/Rules目录下自动创建StoreTicketTypeQuantity.php文件。
2. 编写核心验证逻辑
打开生成的规则文件,替换passes和message方法的内容,实现针对每种票型的数量校验:
<?php namespace App\Rules; use Illuminate\Contracts\Validation\Rule; use App\Models\TicketType; class StoreTicketTypeQuantity implements Rule { // 用于存储错误信息的变量(可选优化) private $errorDetails = []; /** * 验证规则是否通过 * * @param string $attribute * @param mixed $value * @return bool */ public function passes($attribute, $value) { // $value就是提交的types数组,格式如["ticket type 1" => "2", "ticket type 2" => "1"] foreach ($value as $ticketTypeName => $quantity) { // 把数量转为整数,避免字符串格式干扰 $quantity = (int)$quantity; // 根据票型名称查找对应的数据库记录 $ticketType = TicketType::where('name', $ticketTypeName)->first(); // 情况1:票型不存在,直接验证失败 if (!$ticketType) { $this->errorDetails = [ 'type' => $ticketTypeName, 'message' => '不存在该票型' ]; return false; } // 情况2:数量超出minPerUser和maxPerUser范围,验证失败 if ($quantity < $ticketType->minPerUser || $quantity > $ticketType->maxPerUser) { $this->errorDetails = [ 'type' => $ticketTypeName, 'min' => $ticketType->minPerUser, 'max' => $ticketType->maxPerUser ]; return false; } } return true; } /** * 获取验证错误提示信息 * * @return string */ public function message() { // 根据不同错误场景返回精准提示 if (isset($this->errorDetails['message'])) { return "票型「{$this->errorDetails['type']}」不存在,请检查后重试。"; } return "票型「{$this->errorDetails['type']}」的购买数量不符合要求,每人限购{$this->errorDetails['min']}-{$this->errorDetails['max']}张。"; } }
注意:如果你的
TicketType表中用slug或其他字段作为票型标识,记得把where('name', $ticketTypeName)改成对应的字段名。
3. 在控制器中使用该规则
在RegistrationController的存储方法里,把这个自定义规则加到验证逻辑中:
use App\Rules\StoreTicketTypeQuantity; // ... public function store(Request $request) { $validatedData = $request->validate([ 'types' => ['required', 'array', new StoreTicketTypeQuantity], // 先给每个数量做基础校验:必须是正整数 'types.*' => 'required|integer|min:1' ]); // 验证通过后,执行后续的订单创建等业务逻辑... }
这样用户提交的每种票型数量都会被严格校验,不符合规则时会返回清晰的错误提示。
内容的提问来源于stack exchange,提问作者johnW
相关产品推荐
相关产品推荐

