https://laraveldaily.com/storage/423/Copy-of-Copy-of-ModelpreventLazyLoading();-(6).png
When uploading files with Laravel, how to store the filename in the DB? Should you store filename.png
? Or, include the folder of avatars/filename.png
? Or, the full path https://website.com/avatars/filename.png
? Let me tell you my opinion.
This tutorial will have an avatar
field on the register page and an avatar
column in the users
table. Let’s see how we can save it.
The easiest way is to store just the filename and create a separate storage disk.
config/filesystems.php:
return [
// ...
'disks' => [
// ...
'avatars' => [
'driver' => 'local',
'root' => storage_path('app/public/avatars'),
'url' => env('APP_URL').'/storage/avatars',
'visibility' => 'public',
'throw' => false,
],
],
// ...
];
Then, when storing the file we need to specify the new avatars
disk.
app/Http/Controllers/Auth/RegisteredUserController.php:
class RegisteredUserController extends Controller
{
// ...
public function store(Request $request): RedirectResponse
{
$request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:'.User::class],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
'avatar' => ['nullable', 'image'],
]);
if ($request->hasFile('avatar')) {
$avatar = $request->file('avatar')->store(options: 'avatars');
}
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
'avatar' => $avatar ?? null,
]);
// ...
}
}
This way, your full URL filename https://website.com/storage/avatars/filename.png
consists of three things:
-
Domain:
https://website.com
is stored in yourAPP_URL
in.env
file: so it is flexibly different for your local and production servers -
Folder:
/storage/avatars
is in theconfig('disks.avatars.url')
which corresponds to the internal structure of/storage/app/public/avatars
described in the same config file. Both also can be flexibly changed if needed. -
Filename:
filename.png
is the only thing actually landing in the DB column
To get the URL for the image in the Blade file, we would use URL method on the Storage
facade providing the disk.
<img src="" alt="" />
But what if, after some time, you would need to go from local disks to, let’s say, Amazon S3?
The only change you would need to make is to change the disk, and maybe instead of the url
, use the temporaryUrl
method to provide the expiration time for the link.
<img src="" alt="" />
Laravel News Links