用户肯定都要有自己的头像,这就涉及到了图片的上传、裁剪等,其实很容易实现。
图片上传
直接使用file类型的input标签即可,我们可以通过accept属性来限制上传的文件类型,但是一般避免使用此属性,建议在服务器端验证文件上传。
<input type="file" name="avatar" accept="image/png, image/jpeg">
这里有一点要注意,图片或文件上传时,必须为表单添加enctype声明,否则请求对象$request获取的就会是图片名称。
<form action="{{ route('users.update', $user->id) }}" method="POST"
accept-charset="UTF-8"
enctype="multipart/form-data">
可以在控制器中直接使用请求对象Request来获取上传的文件
$file = $request->avatar; //avatar就是input标签的name属性值
但是,肯定不能获取到图片后直接存到数据库,那就太愚蠢了。一般情况下,图片上传功能是系统中经常使用的功能,所以可以将图片上传做成一个工具类,需要用到的时候就直接调用即可。
namespace App\Handlers;
use Illuminate\Support\Str;
class ImageUploadHandler
{
// 只允许以下后缀名的图片文件上传
protected $allowed_ext = ["png", "jpg", "gif", 'jpeg'];
public function save($file, $folder, $file_prefix)
{
//路径
$folder_name = "uploads/images/$folder/" . date("Ym/d", time());
$upload_path = public_path() . '/' . $folder_name;
// 获取文件的后缀名,因图片从剪贴板里黏贴时后缀名为空,所以此处确保后缀一直存在
$extension = strtolower($file->getClientOriginalExtension()) ?: 'png';
// 文件名
$filename = $file_prefix . '_' . time() . '_' . Str::random(10) . '.' . $extension;
// 如果上传的不是图片将终止操作
if ( ! in_array($extension, $this->allowed_ext)) {
return false;
}
// 将图片移动到我们的目标存储路径中
$file->move($upload_path, $filename);
return [
'path' => config('app.url') . "/$folder_name/$filename"
];
}
}
接下来就可以在控制器中调用预先定义的图片上传工具类了。
use App\Handlers\ImageUploadHandler;
class UsersController extends Controller
{
.
.
.
public function update(UserRequest $request, ImageUploadHandler $uploader, User $user)
{
$data = $request->all();
if ($request->avatar) {
$result = $uploader->save($request->avatar, 'avatars', $user->id);
if ($result) {
$data['avatar'] = $result['path'];
}
}
$user->update($data);
return redirect()->route('users.show', $user->id)->with('success', '图片上传成功!');
}
}
图片格式、分辨率限制
图片的格式、分辨率等可以很巧妙的通过表单验证功能进行限制。
public function rules()
{
return [
'name' => 'required|between:3,25|regex:/^[A-Za-z0-9\-\_]+$/|unique:users,name,' . Auth::id(),
];
}
public function messages()
{
return [
'avatar.mimes' =>'头像必须是 jpeg, bmp, png, gif 格式的图片',
'avatar.dimensions' => '图片的清晰度不够,宽和高需要 208px 以上',
];
}
图片的裁剪
composer备受推崇的主要原因就是可以方便的安装扩展包并处理好依赖关系,而此处图片的裁剪我们就通过composer安装一个叫Intervention/image的扩展包来处理图片的裁剪。
Composer安装扩展包
compser require intervention/image
必须在图片处理类里引用Image包,直接调用其中封装好的方法即可。
//裁剪方法
public function reduceSize($file_path, $max_width)
{
// 先实例化,传参是文件的磁盘物理路径
$image = Image::make($file_path);
// 进行大小调整的操作
$image->resize($max_width, null, function ($constraint) {
// 设定宽度是 $max_width,高度等比例缩放
$constraint->aspectRatio();
// 防止裁图时图片尺寸变大
$constraint->upsize();
});
// 对图片修改后进行保存
$image->save();
}