我有一个函数,它接受提交的表单数据,即图像,然后验证它,如果旧图像已经存在,它会删除旧图像。它目前正在执行此操作,并将图像存储在存储文件夹中。
我现在正试图将图像的URL保存到数据库中。我看到过一些例子,他们不保存数据库的路径,但这样做最好吗?
这是我的功能
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]);
}
我主要存储人们从Laravel上传到公共文件夹中的子文件夹的图像。然后,只需您的Web服务器就可以请求图像,而不必通过PHP提供图像。
对于像化身这样的图像,我基于模型的名称和id创建了一个文件夹结构。类似:laravel_folder/public/images/user/13/avatar.jpg。
因为路径和url是基于模型名和id的,所以你可以很容易地生成一个直接的url和路径。缺点是其他用户的头像的url和道路是可预测的,所以不要将其用于敏感图像。
我看到您接受多种格式的图像(jpg、png、bmp)。保存图像时,会将其另存为jpg图像。您应该使用像Intervention这样的图像操作库,或者使用pathinfo获取文件的扩展名($file,pathinfo_extension),否则文件将无法读取,因为图像扩展名和图像内容不匹配。
还要考虑图像大小。用户可以上传海报大小的图片,而你只需要一张小图片。使用图像操作库可以创建原始图像的较小版本图像。
如果您将原始图像保存为从用户那里获得的格式,那么只需检查所有扩展(如果存在)。一种方法是:
$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;
}
}
文件路径中存储的内容越少越好,因为您没有被任何文件夹结构锁定。
目前,你可能会将所有上传的内容存储在/public/uploads中,但当你的应用程序变得更大时,你可能想将所有内容都放在/public/uploads/form_xyz_images中。当您将整个图像路径放入数据库时,您必须调整数据库中的所有值。
更好的方法是只保存文件名并将路径附加到其他地方。例如,您可以使用访问器和赋值器来获取路径:https://laravel.com/docs/master/eloquent-mutators#accessors-和突变体