Joey93
Joey93

Reputation: 103

Saving image path to database using Laravel

I have a function that takes submitted form data which is an image, then validates it and it deletes an old image if one already exists. It currently does that and stores the image on in the storage folder.

I am now trying to save the URL of the image to the database. I have seen examples where they do not save the path to the database but would it be best to do so?

Here is my function

public function postAvatarUpload(Request $request)
    {
         $this->validate($request, [
            'image' => 'required|image|max:3000|mimes:jpeg,jpg,bmp,png',
        ]);
        $user = Auth::user();
        $usersname = $user->username;
        $file = $request->file('image');
        $filename = $usersname . '.jpg';
        if (Storage::disk('local')->has($filename)) {
            Storage::delete($filename);
        }
           Storage::disk('local')->put($filename, File::get($file));
           $avatarPath = Storage::url($filename);
            Auth::user()->update([
                'image' => $avatarPath,
            ]);

        return redirect()->route('profile.index', 
                ['username' => Auth::user()->username]);
    }

Upvotes: 0

Views: 3858

Answers (2)

blablabla
blablabla

Reputation: 1478

I mostly store images people upload to a subfolder in the public folder from Laravel. The image can then be requested with only your webserver doing the work and not having to serve it via PHP.

For images like an avatar I create a folder structure based on the model name and id of the model. Like: laravel_folder/public/images/user/13/avatar.jpg.

Because the path and url are based on the modelname and id, you can easily generate a direct url and path to it. Downside is that the url and path to avatars of other users is predictable, so don't use it for sensitive images.

I see you accept an image in multiple formats (jpg,png,bmp). When you save the image, you save it as an jpg image. You should use an image manipulation library like Intervention, or get the extension of the file with pathinfo($file, PATHINFO_EXTENSION), otherwise the file won't be readable because the image extension and the image contents don't match.

Also think about the image size. Users can upload an image in poster size, while you only need a small image. Use an image manipulation library to create a smaller version image of the original image.

If you save the original image in the format you get from the user, then just check all extensions if they exist. One way to do it would be:

$extensions = [ 'jpg', 'jpeg', 'png', 'bmp' ];

$user = Auth::user();

$imagePath = "{public_path()}/images/{class_basename($user)}/{$user->id}/";
$imageName = "avatar";

// go through all extensions and remove image if it exists
foreach($extensions as $ext)
{
    $imageFullPath = "{$imagePath}/{$imageName}.{$ext}";

    if( file_exists($imageFullPath) )
    {
        @unlink($imageFullPath);
        break;
    }
}

Upvotes: 1

Tim Van Dijck
Tim Van Dijck

Reputation: 552

The less you store in your filepath, the better because you aren't locked down to any folderstructure.

For now you might store all your uploads in /public/uploads but when your app gets bigger you might want to put everything in /public/uploads/form_xyz_images. When you put your whole image path in the database you'll have to adjust all values in the database.

A better way would be to only save the filename and append the path somewhere else. For example you could use accessors and mutators to get the path: https://laravel.com/docs/master/eloquent-mutators#accessors-and-mutators

Upvotes: 0

Related Questions