amir5's avatar
Level 7

Do you prepend public uploaded file path with storage

When I upload a file in public disk, it returns its path after storage/app/public, and to display it because it's under public/storage, I should do asset('storage/'.$path) wherever I want to use it. Is there any drawbacks of storing path including storage in database and read it like this asset($path)?? Or another option can be using accessors

0 likes
3 replies
Snapey's avatar
Snapey
Best Answer
Level 122

you can set url on the storage configuration if not already set.

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

then in your view, the path is obtained as

<img src="{{ Storage::disk('public')->url($path)}}" />

disk() is optional as public will be the default. I sometimes store the disk name in the database as well as the path so that I can migrate images between disks.

<img src="{{ Storage::disk($category->image_disk)->url($category->image}}" />

In your database store the path as relative to the root of the public storage disk.

1 like
amir5's avatar
Level 7

@Snapey I hadn't thought about Storage::disk('public')->url($path), cool. But I wonder why there's no mention of that in public disk section https://laravel.com/docs/11.x/filesystem#the-public-disk

Once a file has been stored and the symbolic link has been created, you can create a URL to the files using the > asset helper:

echo asset('storage/file.txt');
martinbean's avatar

When I upload a file in public disk

@amir5 You shouldn’t be. You shouldn’t be storing any user-uploaded in a publicly-accessible location. If a user manages to upload a malicious file and then is also able to access it directly via a URL, you’ve now introduced a vulnerability to your application and the server it is running on.

Instead, you should be uploading user files to a storage, and then only serving generated thumbnail versions. This also helps if a user uploads say, a 4 MB image that you only need to display in a space that’s say, 300 pixels wide. You’re just wasting bandwidth (and increasing load times) if you were to just serve the original, massive files uploaded by users instead of appropriately-sized thumbnails.

So, store uploads in storage as per the Laravel docs…

// Store file in "uploads" directory, and return path
$model->path = $request->file('image')->store('uploads');

…and then either generate predefined thumbnails if you know what size you need them, or use something like Glide to serve dynamic thumbnails.

1 like

Please or to participate in this conversation.