minjon's avatar
Level 15

How to retrieve multiple files from Laravel file storage

I managed to upload multiple files to the file storage, but have a problem retrieving them.

I have a Product and an Image model, with a one-to-many relationship with them.

Schema::create('images', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('product_id')->unsigned();     
    $table->string('filename');
});

ProductController

public function store(ProductRequest $request)
{
    $product = Product::create($request->all());

    if ($files = $request->image)
    {
        foreach ($files as $file)
        {
            $filename = $product->id.'-product.jpg';

            $product->images()->create(['filename' => $filename]);

            $file->storeAs('products', $filename);
        }
    }
}

Route for displaying files and the corresponding method in the ProductController

Route::name('products.file.show')->get('/file/{product}', 'ProductController@showFile');


public function showFile(Product, $product)
{
    foreach($product->images as $image)
    {
        $filename = $image->filename;

        $files = Storage::disk('products')->get($filename);

        return $files;
    }

And finally, the show page

@foreach ($product->images as $image)

    <img src="{{ route('products.file.show', $product->id) }}" />
               
@endforeach

With the code above I get multiple images, but they are all the same - it's always the last in the raw of the uploaded images. What should I change to get all of them correctly?

0 likes
1 reply
ckalita's avatar

Not that you need the answer for this, 6 years later, but the issue with your naming convention:

foreach ($files as $file)
        {
            $filename = $product->id.'-product.jpg';

            $product->images()->create(['filename' => $filename]);

            $file->storeAs('products', $filename);
        }

when your product->id is, say, 1, and you have 3 images (say, image1.jpg, image2.jpg and image3.jpg), they will all be stored with the same name and the last one will essentially overwrite them all:

[
'image1.jpg' => '1-product.jpg',
'image2.jpg' => '1-product.jpg',
'image3.jpg' => '1-product.jpg',
]

Please or to participate in this conversation.