Search code examples
laravelfile-uploadguzzle

Sending images through Laravel Guzzle Client


I am trying to upload multiple images using guzzlehttp client. I load images as a file and loads only one image with the code below.

$clientPAimages = new Client();
$imagesPA = Req::file('images');
foreach($imagesPA as $image){
    $bodyImages[] = [
        'name'         => 'image',
        'contents'     => fopen($image->getRealPath(), 'r'),
        'filename' => $image->getClientOriginalName(),
        'headers'  => [
             'Content-Type' => '<Content-type header>'
        ]
    ];
}
               
$responsePA3 = $clientPAimages->request('POST', 'link/images', [
    'multipart' => $bodyImages
]);
$responsePA3->getBody();

Does anyone have any idea how to solve this i.e. how to save multiple images?


Solution

  • I was in this kind of situation, when i needed to send multiple images from the laravel app to the node.js app. Your code seems ok, but may you've something wrong in your blade, for example usage of enctype="multipart/form-data" in the form, or name="images[]" as an input property, or something like that.

    Anyway i'll share here the snippet, which worked well for me before, so i guess it can be useful.

    Specifications for this snippet was:

    • "laravel/framework": "^8.12",
    • "guzzlehttp/guzzle": "^7.0.1",

    create.blade.php

    <form action="http://internal.site/upload" method="post" enctype="multipart/form-data">
        @csrf
        <input id="ss_images"
               name="images[]"
               type="file"
               multiple="multiple"
               class="input"
               accept=".jpeg,.bmp,.png,.jpg,.gif"
        />
        <div class="mt-3">
            <label class="{{ $errors->has('name') ? 'has-error' : '' }}">
                {{ $errors->has('name') ? $errors->first('name') : "Name" }}
            </label>
            <input value="{{ old('name') }}" type="text" class="input" placeholder="Name" name="name">
        </div>
        <div class="mt-3">
            <label class="{{ $errors->has('description') ? 'has-error' : '' }}">
                {{ $errors->has('description') ? $errors->first('description') : "Description" }}
            </label>
            <textarea class="input" placeholder="Description" name="description">{{ old('description') }}</textarea>
        </div>
    </form>
    

    ItemController.php

    use GuzzleHttp\Client;
    
    // ...
    
    public function upload(Request $request)
    {
        $data = $request->only([
            'name',
            'description',
        ]);
    
        $multipart = [];
        if($request->hasFile('images')) {
            foreach ($request->file('images') as $k => $image) {
                $multipart[] = [
                    'name' => 'file',
                    'contents' => fopen($image->getRealPath(), 'r'),
                    // ... some additional fields
                ];
            }
        }
    
        // adding some text-oriented data if need
        $multipart[] =  [
            'name' => 'data',
            'contents' => json_encode($data, true),
        ];
    
        $client = new Client();
        $url = "http://external.site/link/images";
        $response = $client->request('POST', $url, [
            'multipart' => $multipart
        ]);
    
        $res_json = $response->getBody()->getContents();
        $res = json_decode($res_json, true);
    
        return redirect()->back()->with([
            'success' => $res['success'],
            'flash_message' => $res['message'],
        ]);
    }
    

    Enjoy!!