I have simplified my form for this question.
This is my example
<form method="post" name="test" enctype="multipart/form-data">
{{csrf_field()}}
<input class="form-control" type="file" name="test[]" id="companion"/>
<input type="hidden" name="test[]" value="random-value" />
<input type="submit" value="Submit">
</form>
In my route a just dd the request as follow:
dd(request('test'));
Now I would expect an array with a file (UploadedFile type) and the random-value, instead, I'm getting only the file.
array:1 [▼
0 => UploadedFile {#539 ▶}
]
Any idea why I'm getting this result? I know that I can change the name of the variables, but I wanna understand why it doesn't work like that.
Thanks in advance.
Ok, I might have found a solution.
Since I'm editing, I know if the file/hidden input is new (as in the edit I can add other items) or got from the DB.
<form method="post" name="test" enctype="multipart/form-data">
{{csrf_field()}}
<input class="form-control" type="file" name="test[]" id="companion"/>
<input type="hidden" name="test[id-{{id}}]" value="random-value" />
<input type="submit" value="Submit">
</form>
With this "fix" I will manage to get my goal.
dd(request('test'));
------------------------
array:2 [▼
"id-1" => "random-value"
0 => UploadedFile {#539 ▶}
]
I do not care about the keys so I'm happy with this solution.
NB this is just a simplification of my problem but it helped me to understand it.
I hope it'll help other people =)
Feel free to ask me if you have any question ;)
Cheers.
It's because:
You call request('test')
. This made a call to the helper in Illuminate\Foundation\helpers.php
function request($key = null, $default = null)
{
...
$value = app('request')->__get($key);
...
}
This directs the call to the __get
method to quickly get a value in Illuminate\Http\Request.php
public function __get($key)
{
if (array_key_exists($key, $this->all())) {
return data_get($this->all(), $key);
}
...
}
The problem lies in the all()
method defined in the trait Illuminate\Http\Concerns\InteractsWithInput
public function all($keys = null)
{
$input = array_replace_recursive($this->input(), $this->allFiles());
if (! $keys) {
return $input;
}
...
}
So you see what's going on here? You actually still have the test[]
hidden value, but the all()
method simply merged it with files with the same name. I assume it's for the sake of simplicity on why they would do this, and I don't think it's that common to have two inputs with the same name, with different input type.
I guess, the simplest solution here now is, to access it via the request
instance. Try this (untested, theoretically should work):
\Log::info(app('request')->file('test'));
\Log::info(app('request')->get('test'));
And find the output in laravel.log
file. You should be able to do a simple array merge with them.