harunB10
harunB10

Reputation: 5207

Upload file using Guzzle

I have a form where video can be uploaded and sent to remote destination. I have a cURL request which I want to 'translate' to PHP using Guzzle.

So far I have this:

public function upload(Request $request)
    {
        $file     = $request->file('file');
        $fileName = $file->getClientOriginalName();
        $realPath = $file->getRealPath();

        $client   = new Client();
        $response = $client->request('POST', 'http://mydomain.de:8080/spots', [
            'multipart' => [
                [
                    'name'     => 'spotid',
                    'country'  => 'DE',
                    'contents' => file_get_contents($realPath),
                ],
                [
                    'type' => 'video/mp4',
                ],
            ],
        ]);

        dd($response);

    }

This is cURL which I use and want to translate to PHP:

curl -X POST -F 'body={"name":"Test","country":"Deutschland"};type=application/json' -F 'file=@C:\Users\PROD\Downloads\617103.mp4;type= video/mp4 ' http://mydomain.de:8080/spots

So when I upload the video, I want to replace this hardcoded

C:\Users\PROD\Downloads\617103.mp4.

When I run this, I get an error:

Client error: POST http://mydomain.de:8080/spots resulted in a 400 Bad Request response: request body invalid: expecting form value 'body`'

Client error: POST http://mydomain.de/spots resulted in a 400 Bad Request response: request body invalid: expecting form value 'body'

Upvotes: 6

Views: 12931

Answers (3)

Think Big
Think Big

Reputation: 1517

if the php is on the target server thenfilename is required !

Upvotes: 0

R Sun
R Sun

Reputation: 1679

  • While using the multipart option, make sure you are not passing content-type => application/json :)
  • If you want to POST form fields AND upload file together, just use this multipart option. It's an array of arrays where name is form field name and it's value is the POSTed form value. An example:
'multipart' => [
                [
                    'name' => 'attachments[]', // could also be `file` array
                    'contents' => $attachment->getContent(),
                    'filename' => 'dummy.png',
                ],
                [
                    'name' => 'username',
                    'contents' => $username
                ]
            ]

Upvotes: 1

Jacob Budin
Jacob Budin

Reputation: 10003

I'd review the Guzzle's multipart request options. I see two issues:

  1. The JSON data needs to be stringified and passed with the same name you're using in the curl request (it's confusingly named body).
  2. The type in the curl request maps to the header Content-Type. From $ man curl:

    You can also tell curl what Content-Type to use by using 'type='.

Try something like:

$response = $client->request('POST', 'http://mydomain.de:8080/spots', [
    'multipart' => [
        [
            'name'     => 'body',
            'contents' => json_encode(['name' => 'Test', 'country' => 'Deutschland']),
            'headers'  => ['Content-Type' => 'application/json']
        ],
        [
            'name'     => 'file',
            'contents' => fopen('617103.mp4', 'r'),
            'headers'  => ['Content-Type' => 'video/mp4']
        ],
    ],
]);

Upvotes: 12

Related Questions