Search code examples
laravelstoragelaravel-storage

How to retrieve file from Laravel storage subfolder?


I'm trying to retrieve a file from this path in a laravel project:

/storage/app/public/blog/3.jpg

These approaches produce following errors:

1.

$image = Storage::disk('public')->get('/storage/blog/3.jpg');

->

local.ERROR: File not found at path: storage/blog/3.jpg {"userId":16,"exception":"[object] (Illuminate\\Contracts\\Filesystem\\FileNotFoundException(code: 0): File not found at path: storage/blog/3.jpg at /Users/artur/PhpstormProjects/safa-ameedee.com/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php:171)
[stacktrace]
$image = Storage::disk('public')->get('/storage/app/public/blog/3.jpg');
$image = Storage::get('/storage/app/public/blog/3.jpg');

->

local.ERROR: File not found at path: storage/app/public/blog/3.jpg {"userId":16,"exception":"[object]

The weird thing is that I store the files in the storage like so:

Storage::disk('public')->put('/blog/' . $request->path, $image);

So should they not be retrievable in the same way?


Solution

  • TL/DR

    Storage::disk('public')->get('block/3.jpg');
    

    Explanation

    The problem is you're putting storage in the path for some reason. It's not necessary and is leading to the wrong path being built.

    Take a look at the default filesystems config:

    'disks' => [
        'local' => [
            'driver' => 'local',
            'root' => storage_path('app'),
            'throw' => false,
        ],
        'public' => [
            'driver' => 'local',
            'root' => storage_path('app/public'),
            'url' => env('APP_URL').'/storage',
            'visibility' => 'public',
            'throw' => false,
        ],
    

    The root is what is useful to see here. storage_path() returns the full path to the storage folder. So something like storage_path('folder_1') -> /home/user/project/storage/folder_1.

    The local disk is the default, so just doing Storage::get() will use it automatically.

    You're using the public disk, so the actual location of these files is storage/public (symlinked into public/storage). This means doing Storage::disk('public') already begins at /home/user/project/storage/app/public. Adding storage again makes the path incorrect.

    Using path may help with future debugging. Storage::disk('public')->path('block/3.jpg') will output the full path, and you can see where it's going wrong. For your code given it would probably show something like /home/user/project/storage/app/public/storage/app/public.