本书未发布

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 '限制头像分辨率'

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~