Repository navigation
Replies: 1 comment
|
hi rgpgf, Understanding the Behavior of
|
| Method | Reads from | Sees merge()? |
|---|---|---|
validated() |
Internal array inside $this->validator — captured at Step 1 |
❌ No |
safe() |
Wraps $this->validator — captured at Step 1 |
❌ No |
input() |
Request ParameterBag — updated at Step 2 |
✅ Yes |
only() |
Request ParameterBag — updated at Step 2 |
✅ Yes |
all() |
Request ParameterBag — updated at Step 2 |
✅ Yes |
Is This Intended?
Yes — but it is an undocumented footgun. The passedValidation() hook was designed for
side effects (e.g. firing events, setting state), not for mutating the validated dataset. Using
$this->merge() inside it and expecting validated() / safe() to reflect those changes is
effectively an anti-pattern given the current architecture.
Recommended Solutions
✅ Option 1 — Use prepareForValidation() (best when transform logic doesn't depend on other validated values)
protected function prepareForValidation(): void
{
$this->merge([
'user_data' => $this->transformUserData(),
]);
}prepareForValidation() runs before the validator captures data, so the merged value is
present in both the ParameterBag and the validator's internal array — as long as user_data
appears in rules(). This makes validated(), safe(), input(), and all() consistent.
⚠️ Limitation: Not viable if your transform depends on reading another field's validated
result first.
✅ Option 2 — Override validated() directly in the FormRequest
public function validated($key = null, $default = null): array
{
return array_merge(parent::validated(), [
'user_data' => $this->transformUserData(),
]);
}Clean and self-contained. Every call to validated() returns the transformed data.
⚠️ Note:safe()calls$this->validator->validated()internally, bypassing this
override entirely. If you rely onsafe(), this option does not help for that method.
✅ Option 3 — Transform explicitly in the controller (most explicit, no surprises)
public function store(MyFormRequest $request): JsonResponse
{
$data = array_merge($request->validated(), [
'user_data' => $this->transformUserData($request),
]);
}The clearest data-flow story. The FormRequest handles authorization and validation;
transformation is an explicit step in the controller. Easy to test, easy to reason about.
The Documentation Gap
The current Laravel docs for FormRequest and passedValidation() make no mention of this
inconsistency. Developers who reach for passedValidation() as a "post-validation transform
hook" will hit this silently — nothing throws, nothing warns, and input() / all() will
appear to work correctly until they switch to validated().
A note in the passedValidation() docblock — or a callout in the FormRequest documentation —
clarifying that $this->merge() does not propagate to validated() / safe() would prevent
a lot of confusion.
Uh oh!
There was an error while loading. Please reload this page.
Hi.
When using
passedValidation()in aFormRequestto mutate request data via$this->merge(), the changes are not reflected invalidated()orsafe(), but are reflected inonly(),input(), andall().Example:
After the above runs:
$request->validated()$request->safe()$request->only()$request->input()$request->all()validated()andsafe()read data directly from the internal$this->validatorsnapshot, which is captured beforepassedValidation()is called.$this->merge()only updates theParameterBag, leaving the validator snapshot untouched.Question:
Is this the intended behavior? If so, what is the recommended way to transform/mutate validated data within a
FormRequestso thatvalidated()andsafe()return the transformed values?Documentation gap:
The current Laravel documentation for
FormRequestand thepassedValidation()hook does not mention this inconsistency or any limitation around mutating data that is later accessed viavalidated()/safe(). Developers can reasonably expect that calling$this->merge()insidepassedValidation()would be reflected in all data-access methods, includingvalidated().A documentation note or in-code docblock clarifying this behavior would prevent confusion.
Environment:
All reactions