Laravel验证后facilities与additional_facilities字段缺失求助
问题概述
开发Laravel房源创建功能时,请求中存在的facilities和additional_facilities字段,通过PropertyStoreRequest验证后未出现在$validatedData中,仅amenities字段正常保留。日志显示原始请求包含这两个字段,且无验证错误提示。
相关代码
请求验证类(PropertyStoreRequest)
class PropertyStoreRequest extends FormRequest { public function authorize(): bool { return auth()->user()->isHost(); } public function rules(): array { return [ 'title' => 'required|string|max:255', 'description' => 'required|string', 'location' => 'required|string|max:255', 'price_per_night' => 'required|numeric|min:0', 'max_guests' => 'required|integer|min:1', 'photos' => 'required|array|min:3', 'photos.*' => 'image|mimes:jpg,jpeg,png|max:2048', 'facilities' => 'required|array', 'facilities.*' => 'integer|exists:facilities,id', 'additional_facilities' => 'nullable|array', 'additional_facilities.*' => 'integer|exists:additional_facilities,id', 'amenities' => 'required|array', 'amenities.*' => 'integer|exists:amenities,id', ]; } protected function failedValidation(Validator $validator) { Log::error('Validation failed:', $validator->errors()->all()); throw new HttpResponseException(response()->json([ 'errors' => $validator->errors(), ], 422)); } }
控制器store方法
public function store(PropertyStoreRequest $request) { Log::info('Property coming data:', $request->all()); $validatedData = $request->validated(); // Facilities and additional_facilities missing // Create property $property = Property::create([ 'title' => $validatedData['title'], 'description' => $validatedData['description'], 'location' => $validatedData['location'], 'price_per_night' => $validatedData['price_per_night'], 'max_guests' => $validatedData['max_guests'], 'photos' => json_encode($this->handleFileUpload($request, 'photos', 'property_photos')), 'user_id' => auth()->id(), 'is_available' => $validatedData['is_available'] ?? true, ]); // Syncing relations $this->syncRelations($property, $validatedData, $request); return response()->json($property, 201); }
日志输出
[2024-10-24 13:45:01] local.INFO: Property coming data: {...}
[2024-10-24 13:45:01] local.INFO: validated data from request : {... "amenities":["1","2"], "photos":[...]}
[2024-10-24 13:45:01] local.INFO: Facilities to sync: []
[2024-10-24 13:45:01] local.INFO: Additional Facilities to sync: []
[2024-10-24 13:45:01] local.INFO: Amenities to sync: [1,2]
已排查步骤
- 数据库验证:
facilities和additional_facilities表中存在请求匹配的有效ID。 - 手动测试:验证后手动设置这两个字段,关系同步正常,排除同步环节问题。
解决方案及排查方向
检查
validated()方法是否被重写
查看PropertyStoreRequest或其继承的父类是否重写了validated()方法,若有自定义逻辑可能导致字段被过滤。默认的validated()方法会返回所有通过验证的字段,若被修改需确保包含facilities和additional_facilities。排查全局请求中间件
检查项目中全局注册的请求中间件,确认是否存在对请求字段进行过滤、修改的逻辑,比如某些中间件会移除特定字段或仅保留指定字段。验证前确认字段存在性
在PropertyStoreRequest中添加prepareForValidation方法,打印验证前的字段值,确认字段在验证阶段是否存在:protected function prepareForValidation() { Log::info('Pre-validation facilities:', $this->input('facilities')); Log::info('Pre-validation additional_facilities:', $this->input('additional_facilities')); }若日志中显示字段不存在,需检查请求数据的传递方式(比如表单提交、JSON请求的Content-Type是否正确)。
直接获取字段测试
在控制器中临时添加代码,直接从请求中获取字段:Log::info('Direct facilities:', $request->input('facilities')); Log::info('Direct additional_facilities:', $request->input('additional_facilities'));若能正常获取,说明
validated()方法存在异常;若无法获取,说明请求数据未正确传递到后端。检查Laravel版本兼容性
若使用较旧的Laravel版本,可能存在数组验证后字段未正确返回的bug,尝试升级到稳定版本(如Laravel 10+)测试。验证规则调整
临时调整facilities的验证规则,去掉exists约束,仅保留required|array,测试是否能出现在$validatedData中,以此排查是否是exists规则导致的字段过滤。
内容的提问来源于stack exchange,提问作者data data

