-
Notifications
You must be signed in to change notification settings - Fork 11.7k
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.