Laravel Request类prepareForValidation修改在$request->get中不生效(Octane环境)
问题原因
这确实和Octane的常驻内存机制有关,核心是Laravel Request类的属性缓存未被Octane正确重置:
- 在
prepareForValidation方法中,直接访问$this->emails时,Laravel的Request类会将该值缓存到自身的$attributes数组中,这是Laravel为优化访问速度增加的缓存逻辑。 - 本地环境下,每个请求都会创建全新的Request对象,
$attributes数组每次都是空的,后续操作不会受缓存影响:merge去重后的数组会正确覆盖请求原始数据,$request->get('emails')能拿到处理后的数组。 - Octane环境下,Request对象会被复用而非每次请求新建,Octane的重置逻辑只会清理Symfony Request层面的属性,不会清空Laravel Request类自身的
$attributes缓存数组。当处理新请求时:- 若上一次请求的
$attributes['emails']缓存未被清空,prepareForValidation中访问$this->emails会直接返回旧缓存值,而非当前请求的原始数据,导致去重逻辑失效; - 即使去重逻辑正常执行,
$attributes中缓存的旧原始数组可能会干扰$request->get()方法的取值,get()底层依赖的all()方法在某些场景下会优先读取缓存属性。
- 若上一次请求的
为什么
$request->input()能解决问题? $request->input()方法会直接从当前请求的原始输入源(POST/GET参数)读取数据,不会使用Laravel Request类的$attributes缓存数组,因此能正确获取到prepareForValidation中merge后的去重数组。
更稳妥的解决方案
除了改用input(),还可以在prepareForValidation中避免直接访问属性,改用$this->input('emails')来获取原始数据,从根源上避免缓存问题:
$this->merge([ 'emails' => array_unique($this->input('emails')) ]);
内容的提问来源于stack exchange,提问作者Alper
相关产品推荐
相关产品推荐

