Description
After the recent changes (I did composer update
a couple of minutes ago) you can't submit a form if you have enctype="multipart/form-data"
and input[type="file"]
and leaves the input field empty (no file selected).
Fatal error: Uncaught exception 'InvalidArgumentException' with message 'An uploaded file must be an array or an instance of UploadedFile.' in /var/www/foobar/public/liferaft/file-upload-fails/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/FileBag.php on line 59
Reproduce
1.
composer create-project laravel/laravel . dev-develop
2.
php artisan clear-compiled
3.
Set debug
to true
in config/app.php
.
4.
Open up app/Providers/RouteServiceProvider.php
and change the map
method to this:
$router->group(['namespace' => 'App\Http\Controllers'], function() use ($router) {
$router->get('/', 'HomeController@index');
$router->put('/', 'HomeController@put');
});
5.
Add the following code to app/Http/HomeController.php
:
public function put() {
dd(\Input::all());
}
6.
Change resources/views/hello.php
to this:
<!doctype html>
<html lang="en">
<body>
<form method='post' enctype='multipart/form-data'>
<input type='hidden' name='_method' value='put' />
<input type='hidden' name='_token' value='<?= csrf_token(); ?>' />
<input type='file' name='image' />
<button>Send</button>
</form>
</body>
</html>
If you try to submit the form without selecting a file you will get Uncaught exception 'InvalidArgumentException' with message 'An uploaded file must be an array or an instance of UploadedFile.'
, but if you select an image, you will get an array from Input::all()
.
Bad (temporary) solution
A solution is to remove an file arrays with a null
value before using the SymfonyRequest::dublicate
method.
Change the content of the createFromBase
method from
if ($request instanceof static) return $request;
return (new static)->duplicate(
$request->query->all(), $request->request->all(), $request->attributes->all(),
$request->cookies->all(), $request->files->all(), $request->server->all()
);
to
if ($request instanceof static) return $request;
$files = [];
foreach ($request->files->all() as $index => $file) {
if (null !== $file) $files[$index] = $file;
}
return (new static)->duplicate(
$request->query->all(), $request->request->all(), $request->attributes->all(),
$request->cookies->all(), $files, $request->server->all()
);
You can now submit the form without selecting a file.