使用thinkphp开发app后端中,须要实现一个处理上传图片队列的功能php
这是个上传多图片保存而且须要对其中一张图片进行压缩的功能
(使用的html5 mui框架开发app,若是直接载入原图,app客户端列表中图稍微多几张就会使得webview十分卡顿,建议在开发中,必定要对用户上传的图片进行服务器端的压缩)html
以前已经写过一篇关入如何使用html5+的uploader上传多张图片到服务器的博客:
http://www.cnblogs.com/devilyouwei/p/6790255.html
而且实现了在前端进行压缩的功能(这是第一次压缩,有用户手机端进行)前端
上传到服务器后咱们还需对图片进行处理,我这里使用的php做为后端语言,框架为thinkphp5html5
须要用到thinkphp的File类和Image类
File类:前者获取到用户上传的file(文件)并进行路径和文件名的操做
File类下的方法众多,主要有如下一些,使用以前应该先打印看一下,随意找一个文件测试一下效果,能够看的更加明白些:node
$file = new File(ROOT_PATH."/public/uploads/20170506/abc.jpg"); $arr = [ 'getATime' => $file->getATime(), //最后访问时间 'getBasename' => $file->getBasename(), //获取无路径的basename 'getCTime' => $file->getCTime(), //获取inode修改时间 'getExtension' => $file->getExtension(), //文件扩展名 'getFilename' => $file->getFilename(), //获取文件名 'getGroup' => $file->getGroup(), //获取文件组 'getInode' => $file->getInode(), //获取文件inode 'getLinkTarget' => $file->getLinkTarget(), //获取文件连接目标文件 'getMTime' => $file->getMTime(), //获取最后修改时间 'getOwner' => $file->getOwner(), //文件拥有者 'getPath' => $file->getPath(), //不带文件名的文件路径 'getPathInfo' => $file->getPathInfo(), //上级路径的SplFileInfo对象 'getPathname' => $file->getPathname(), //全路径 'getPerms' => $file->getPerms(), //文件权限 'getRealPath' => $file->getRealPath(), //文件绝对路径 'getSize' => $file->getSize(),//文件大小,单位字节 'getType' => $file->getType(),//文件类型 file dir link 'isDir' => $file->isDir(), //是不是目录 'isFile' => $file->isFile(), //是不是文件 'isLink' => $file->isLink(), //是不是快捷连接 'isExecutable' => $file->isExecutable(), //是否可执行 'isReadable' => $file->isReadable(), //是否可读 'isWritable' => $file->isWritable() //是否可写 ]; print_r($arr); return false;
print_r打印到浏览器后:web
Array ( [getATime] => 1494041766 [getBasename] => abc.jpg [getCTime] => 1494041766 [getExtension] => jpg [getFilename] => abc.jpg [getGroup] => 0 [getInode] => 0 [getLinkTarget] => D:\wamp\www\dashen\public\uploads\20170506\abc.jpg [getMTime] => 1494041766 [getOwner] => 0 [getPath] => D:\wamp\www\dashen\/public/uploads/20170506 [getPathInfo] => SplFileInfo Object ( [pathName:SplFileInfo:private] => D:\wamp\www\dashen\/public/uploads/20170506 [fileName:SplFileInfo:private] => 20170506 ) [getPathname] => D:\wamp\www\dashen\/public/uploads/20170506/abc.jpg [getPerms] => 33206 [getRealPath] => D:\wamp\www\dashen\public\uploads\20170506\abc.jpg [getSize] => 571800 [getType] => file [isDir] => [isFile] => 1 [isLink] => [isExecutable] => [isReadable] => 1 [isWritable] => 1 )
关于如何用thinkphp5处理上传的多张图片文件,专门写一个private方法来处理,最后返回处理好的图片的路径的数组
图片处理包括:ajax
代码:thinkphp
// 用户提交疑难 public function addQues() { // 验证登录session if (!session("?user_info")) return ['info'=>'登陆状态失效', 'login'=>0]; $ajax['title_id'] = input('post.title_id/d'); $ajax['content'] = input('post.content/s'); $ajax['star'] = input("post.star/s"); $ajax['reward'] = input('post.reward/s'); $ajax['message'] = input('post.message/s'); $ajax['price'] = input('post.price/f'); if($ajax['reward']!="金钱悬赏") $ajax['price'] = 0; if ($ajax['title_id'] == null || $ajax['content'] == null || $ajax['star'] == null || $ajax['reward'] == null) return ['info'=>'标题,内容,难度,悬赏方式不能为空', 'status'=>0]; if ($ajax['title_id'] == 0 || $ajax['content'] == "" || $ajax['star'] == "" || $ajax['reward'] == "") return ['info'=>'标题,内容,难度,悬赏方式不能为空', 'status'=>0]; // 上传图片 $ajax['uid'] = session("user_info")['id']; $ajax['create_time'] = time(); $ajax['update_time'] = $ajax['create_time']; $ajax['ip'] = get_client_ip(); if (request()->file() != null) { $imgs = $this->upload(); //根据imgs是否为数组鉴定是否有上传错误和超范围 if(!is_array($imgs)) return['status'=>0,'info'=>$imgs]; $ajax = array_merge($ajax, $imgs); } $ajax['is_del'] = 0; $ajax['is_effect'] = 1; $ajax['state'] = 0; $f = db("Ques")->insert($ajax); if ($f >= 1) return ['status'=>1, 'info'=>'需求单提交成功']; else return ['status'=>0, 'info'=>'数据插入失败']; }
此方法中,压缩第一张图时须要用到原图的文件路径,名称等,我保存在原图同一目录下,在原图前面加上“thumb_”前缀做为区别。数据库
调用upload方法的控制器方法(外部方法):后端
// 文件上传转储(多文件) // 暂且按照UNIX路径存储 private function upload() { //建立的目录名称,日期(相对项目目录。用于数据库保存) $dirName = "public".DS."uploads".DS.(date('Ymd')); //建立保存目录(绝对路径。用于保存文件) $saveDir = ROOT_PATH.DS.$dirName; if (!file_exists($saveDir)){ mkdir($saveDir); } $files = request()->file();//取得上传文件名 foreach ( $files as $key => $file ) { // 自动生成文件名 $info = $file->rule("get_rand")->validate(['ext'=>UPLOAD_EXT,'size'=>UPLOAD_SIZE])->move($saveDir,true,false); if ($info) { //保存到数据的值 $data[$key] = $dirName .DS. $info->getFileName(); } else { return $file->getError(); } // 压缩第一张图 if ($key == 'img0') { $image = Image::open($info->getRealPath()); // 保存 $thumbName = $saveDir.DS.$info->getFilename(); // 绝对路径加上文件名 $save = $saveDir.DS."thumb_" . $info->getFilename(); $image->thumb(300, 200, Image::THUMB_CENTER)->save($save); $data['thumbnail'] = $dirName.DS.$thumbName; } } return $data; } }
注意:thinkphp批量上传可能会出现同名文件覆盖的问题,所以咱们从新规定了rule()方法使用的函数,在common.php写下一个随机生成函数,加上时间戳,这样重复的可能性就几乎为0了,极不易出现重名覆盖问题
同名覆盖问题可能来源于上传文件并发的转储,时间过短了,由于php是秒级别的UNIX时间戳,致使了产生了相同的时间戳,从而用thinkphp官方的文档中的上传示例代码致使了重名覆盖问题
//随机生成器 function get_rand(){ $now = $_SERVER['REQUEST_TIME'];//当前系统时间,比time()多5秒 return rand().$now; }