PHP/Laravel请求验证时嵌套对象转数组如何优雅处理?
Laravel嵌套请求数据校验最优方案
方案1:数组解构直接取值(最简方案)
PHP 7.1及以上版本支持数组解构语法,可在校验完成后直接提取嵌套字段,无需额外赋值行:
['physical_address' => $physicalAddress] = $request->validate([ 'physical_address.street' => ['required', 'string', 'max:255'], 'physical_address.number' => ['required', 'string', 'max:255'], 'physical_address.addition' => ['nullable', 'string', 'max:255'], 'physical_address.zip' => ['required', 'string', 'max:255'], 'physical_address.city' => ['required', 'string', 'max:255'], 'physical_address.country' => ['required', 'string', 'max:255'], ]);
如需转为对象格式,直接强转即可:
$physicalAddress = (object) $physicalAddress;
方案2:单独校验嵌套数组(无外层键直接返回)
使用Validator门面直接对嵌套数组做独立校验,返回结果直接为地址数组,不包含外层physical_address键:
首先顶部引入门面:
use Illuminate\Support\Facades\Validator;
校验代码:
$physicalAddress = Validator::make( $request->input('physical_address', []), [ 'street' => ['required', 'string', 'max:255'], 'number' => ['required', 'string', 'max:255'], 'addition' => ['nullable', 'string', 'max:255'], 'zip' => ['required', 'string', 'max:255'], 'city' => ['required', 'string', 'max:255'], 'country' => ['required', 'string', 'max:255'], ] )->validate();
该方案完全贴合需求,校验逻辑与字段一一对应,无需后续额外提取数据。
方案3:表单请求类封装(适合复杂业务场景)
如果校验逻辑较多,推荐使用Laravel表单请求类统一管理校验规则,自定义方法直接返回格式化后的嵌套数据:
- 生成表单请求类
php artisan make:request ClientStoreRequest
- 编写请求类逻辑
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class ClientStoreRequest extends FormRequest { public function authorize() { return true; } public function rules() { return [ 'type' => ['required', 'string', 'in:b2b,b2c'], 'vat_number' => ['nullable', 'string', 'max:255'], 'company_name' => ['nullable', 'string', 'max:255'], 'legal_entity_type' => ['nullable', 'string', 'max:255'], 'phone' => ['required', 'string', 'max:255'], 'email' => ['required', 'email', 'max:255'], 'first_name' => ['nullable', 'string', 'max:255'], 'last_name' => ['nullable', 'string', 'max:255'], 'date_of_birth' => ['nullable', 'date'], // 物理地址校验 'physical_address.street' => ['required', 'string', 'max:255'], 'physical_address.number' => ['required', 'string', 'max:255'], 'physical_address.addition' => ['nullable', 'string', 'max:255'], 'physical_address.zip' => ['required', 'string', 'max:255'], 'physical_address.city' => ['required', 'string', 'max:255'], 'physical_address.country' => ['required', 'string', 'max:255'], // 账单地址校验规则同上 'billing_address' => ['required', 'array'], 'billing_address.*' => ['required', 'string', 'max:255'], // 联系人数组校验 'contacts' => ['required', 'array'], 'contacts.*.function' => ['required', 'string', 'max:255'], 'contacts.*.first_name' => ['required', 'string', 'max:255'], 'contacts.*.last_name' => ['required', 'string', 'max:255'], 'contacts.*.phone' => ['required', 'string', 'max:255'], 'contacts.*.email' => ['required', 'email', 'max:255'], ]; } // 自定义方法返回格式化后的物理地址对象 public function getPhysicalAddress(): object { return (object) $this->validated('physical_address'); } // 同理可添加返回账单地址、联系人数组的方法 }
- 控制器中调用
public function store(ClientStoreRequest $request) { // 直接获取基础字段数据 $clientData = $request->validated(); // 直接获取物理地址对象 $physicalAddress = $request->getPhysicalAddress(); // 后续业务逻辑 }
该方案代码可复用性高,校验逻辑集中管理,适合中大型项目使用。
内容的提问来源于stack exchange,提问作者Thore
相关产品推荐
相关产品推荐

