Skip to content

Non-POST request body with type multipart/form-data is not present #55174

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
sbbjss opened this issue Mar 26, 2025 · 3 comments
Open

Non-POST request body with type multipart/form-data is not present #55174

sbbjss opened this issue Mar 26, 2025 · 3 comments
Assignees

Comments

@sbbjss
Copy link

sbbjss commented Mar 26, 2025

Laravel Version

12.3.0

PHP Version

8.4.5

Database Driver & Version

No response

Description

Non-POST multipart/form-data requests don't have request body data present unless POST request with _method override is used. This extends on closed issue #13457.

This limitation was recently addressed in PHP 8.4 by including request_parse_body() function, which allows parsing multipart/form-data content for PUT/PATCH requests.

It would be great if Laravel could implement support for this new PHP 8.4 feature.
Working middleware example below:

class HandlePutFormData
{
    public function handle(Request $request, Closure $next)
    {
        if (($request->isMethod('PUT') || $request->isMethod('PATCH')) &&
            str_contains($request->header('Content-Type'), 'multipart/form-data')) {

            $requestWithParsedBody = $request;

            try {
                [$post, $files] = request_parse_body();

                foreach ($post as $key => $value) {
                    $requestWithParsedBody->merge([$key => $value]);
                }

                foreach ($files as $key => $file) {
                    $requestWithParsedBody->files->set($key, $file);
                }

            } catch (RequestParseBodyException $e) {
                Log::error('HandlePutFormData::handle, failed to parse request body: ' . $e->getMessage());
                return $next($request);
            }

            return $next($requestWithParsedBody);
        }

        return $next($request);
    }
}

Steps To Reproduce

  1. Create endpoint accepting PUT, PATCH or DELETE requests:
Route::put('/test-endpoint', function (Request $request) {
    return $request->all();
});
  1. Send a request:
curl -X PUT -H "Content-Type: multipart/form-data" -F "name=test" -F "file=@example.txt" http://localhost:8000/test-endpoint
  1. Observe form fields nor files are accessible in request object.
@macropay-solutions
Copy link

macropay-solutions commented Mar 26, 2025

PHP has issues in parsing PUT for multipart/form-data. The issue has been rose many times.
This is an good idea but not a laravel bug.

@crynobone
Copy link
Member

We'll review this alongside Symfony 7.3: symfony/symfony#59358

@crynobone crynobone self-assigned this Mar 27, 2025
@macropay-solutions
Copy link

@crynobone the situation from that link is a perfect example of unit tests getting in the way of good things.
A simple solution is not implemented after months because of the unit test changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants