本书未发布
53. 限制头像分辨率
简介
为防止用户上传分辨率太小的头像图片影响网站的美观,在这一节里我们对上传图片进行一些限制。
需求分解
对头像图片限制的规则如下:
- 只允许上传 JPG 或 PNG 格式图片;
- 图片宽度和高度都不能小于 200 px。
验证器
使用命令行工具新建一个验证器来完成对上传头像的验证:
$ php think make:validate common/Avatar
验证器代码如下:
application/common/validate/Avatar.php
<?php
namespace app\common\validate;
use think\Validate;
use think\File as ThinkFile;
class Avatar extends Validate
{
protected $rule = [
'file' => 'file|fileMime:image/jpeg,image/png|minWidthAndHeight:200,200',
];
protected $message = [
'file.file' => '头像必须是上传文件',
'file.fileMime' => '头像必须是jpeg或png格式的图片',
'file.minWidthAndHeight' => '头像的清晰度不够,宽和高需要208px以上',
];
/**
* 验证上传头像最小宽高
* @Author zhanghong(Laifuzi)
* @DateTime 2019-02-19
* @param string $value 字段值
* @param string $rule 字段值验证值
* @return string/true 验证结果
*/
public function minWidthAndHeight($file, $rule)
{
if (!($file instanceof ThinkFile)) {
return false;
}
if(empty($rule)){
return false;
}
$rule = explode(',', $rule);
$min_width = intval($rule[0]);
if(isset($rule[1])){
$min_height = intval($rule[1]);
}else{
// 不限制图片高度
$min_height = 0;
}
// 获取上传文件的宽高
list($width, $height) = getimagesize($file->getRealPath());
if($width < $min_width || $height < $min_height){
return false;
}
return true;
}
}
代码解读
- 我们使用框架内置验证里的 上传验证规则 实现对上传文件格式的验证;
- 自定义了一个名为
minWidthAndHeight
的规则来验证上传图片的分辨率。我们之所以不使用image
这个内置规则是因为该方法是验证图片的宽高必须和规则值相等,不是我们想要的效果。
数据模型
我们重构一下 Upload::saveImage ,当上传的图片类型是「用户头像」】时保存之前用 Avatar 验证一下上传图片是否合法。
application/common/model/Upload.php
<?php
namespace app\common\model;
use app\common\validate\Avatar as AvatarValidate;
use app\common\exception\ValidateException;
class Upload
{
/**
* 保存上传图片
* @Author zhanghong(Laifuzi)
* @DateTime 2019-02-21
* @param File $file 上传文件
* @return object FunctionResult
*/
public static function saveImage($file, $type){
$validate = new AvatarValidate;
if(!$validate->batch(true)->check(['file' => $file])){
$e = new ValidateException('上传图片失败');
$e->setData($validate->getError());
throw $e;
}
$local_dir = 'uploads';
$ds = DIRECTORY_SEPARATOR;
.
.
.
}
}
控制器
在控制器里捕获 Upload::saveImage 方法验证失败时抛出的异常:
application/index/controller/Upload.php
<?php
namespace app\index\controller;
use think\Request;
use app\common\model\Upload as UploadModel;
use app\common\exception\ValidateException;
class Upload extends Base
{
.
.
.
private function save_image($request)
{
$backcall = $request->param('backcall');
$width = $request->param('width');
$height = $request->param('height');
$image = $request->param('image');
$error_msg = '';
if($request->isPost()){
$file = $request->file('image');
try{
$upload_info = UploadModel::saveImage($file);
$image = $upload_info['save_path'];
}catch(ValidateException $e){
$errors = $e->getData();
// 获取异常错误提示信息
$error_msg = $errors['file'];
}
}
$this->assign('backcall', $backcall);
$this->assign('width', $width);
$this->assign('height', $height);
$this->assign('image', $image);
$this->assign("error_msg", $error_msg);
return $this->fetch('create');
}
}
视图页面
我们在控制器方法里添加了一个视图变量 $error_msg
,当上传图片验证失败时该字段存储着异常提示信息,所以我们需要在视图页面里显示出该提示信息。
application/index/view/upload/create.html
.
.
.
<form enctype="multipart/form-data" id="PostMe" action="" method="post" name="upform">
<input type="hidden" value="{$error_msg}" id="update-error">
<input type="hidden" value="{$width}" name="width">
<input type="hidden" value="{$height}" name="height">
.
.
.
</form>
.
.
.
{js href="/static/assets/plugins/jquery/jquery.min.js" /}
<script type="text/javascript">
.
.
.
var error_msg = $('#update-error').val();
if(error_msg.length){
// 当错误提示信息不为空时,弹出警告框
alert(error_msg);
}
</script>
效果展示
提交代码
下面把代码纳入到版本管理:
$ git add -A
$ git commit '限制头像分辨率'
推荐文章: