<?php
namespace App\Unloading\Api\Controllers;
use Storage;
use Image;
use Illuminate\Http\Request;
use App\Ship\Controllers\ApiController;
/**********************************
* 文件上传
* formData方式,支持单图、多图上传
* base64方式, 只支持单文件上传
* method: POST
* action: upload
* param: 参数说明
* ①file_type 允许上传的文件后缀,string类型,用逗号隔开
* ②width 缩放宽度
* ③height 缩放高度
* ④dirName 存储文件夹名称,默认
* ⑤upload_type 上传方式,默认formData,可以是base64
**********************************/
class ImgController extends ApiController
{
private $allow_type = array('gif', 'jpg','jpeg', 'png', 'zip', 'rar', 'txt', 'doc', 'pdf');
private $img_type = array('gif','jpg','jpeg','png');//图片格式,用来区分是否是图片上传(!勿动!)
private $pic_dir = 'images'; //默认图片上传目录
private $file_dir = 'files'; //默认文件上传目录
private $upload_max_size = 20971520; //最大上传文件20兆
private $upload_type = 'formData'; //默认上传方式
private $img_width = ''; //默认不限制图片宽度
private $img_height = ''; //默认不限制图片高度
private static $watermark = 'uploads/images/qrcode.png'; //水印图片地址
public function upload(Request $request)
{
$param = $request->all();
//upload_type 上传方式,默认formData,可以是base64
if(isset($param['upload_type']) && !empty($param['upload_type'])){
$this->upload_type = $param['upload_type'];
}
//根据传参调用不同的上传方式
switch ($this->upload_type){
case 'formData':
$data = $this->formData($request);
break;
case 'base64':
//只支持单图上传,key健必须为file
$data = $this->base64($param);
break;
}
return $data;
}
/**
* formData上传方式
* @param $request
* @return array
*/
private function formData($request){
$files = $request->allFiles();
$param = $request->all();
$path = array();
foreach ($files as $k=>$v){
$type = $v->getClientOriginalExtension();//获取后缀
$size = $v->getSize(); //文件大小
//验证是否有文件限制
if(isset($param['file_type']) && !empty($param['file_type'])){
$file_type = explode(',',$param['file_type']);
}else{
$file_type = $this->allow_type;
}
if(!in_array($type,$file_type)){
return ['code'=>301,'msg'=>'不支持'.$type.'文件'];
}
//验证文件大小
if($size > $this->upload_max_size){
return ['code'=>301,'msg'=>'上传文件超过最大限制'];
}
//根据文件类型上传
if(in_array($type,$this->img_type)){
$width = $param['width']??$this->img_width;
$height = $param['height']??$this->img_height;
$dirName = $param['dirName']??$this->pic_dir;
$path[] = self::imgs($v,$width,$height,$dirName);
}else{
$dirName = $param['dirName']??$this->file_dir;
$path[] = self::files($v,$dirName);
}
}
return $path;
}
/**
* @param $param
* @return array 返回图片地址及后缀
*/
private function base64($param){
$img = $param['file'];
$img = str_replace(array('_', '-'), array('/', '+'), $img);
$b64img = substr($img, 0, 100);
if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $b64img, $matches)) {
$type = $matches[2];
//验证是否有文件限制
if(isset($param['file_type']) && !empty($param['file_type'])){
$file_type = explode(',',$param['file_type']);
}else{
$file_type = $this->allow_type;
}
if(!in_array($type,$file_type)){
return ['code'=>301,'msg'=>'不支持'.$type.'文件'];
}
$img = str_replace($matches[1], '', $img);
$img = base64_decode($img);
$randName = 'base64';
//如果是图片存到图片文件夹中,否则存到文件中,如果设置,则都存到设置的文件夹中
if(in_array($type,$this->img_type)){
$dirName = $param['dirName']??$this->pic_dir;
$picture = true;
}else{
$dirName = $param['dirName']??$this->file_dir;
}
$path = self::getUploadPath($randName,$type,$dirName);
file_put_contents($path, $img);
//如果是图片则可以生成缩略图
if($picture){
$width = $param['width']??$this->img_width;
$height = $param['height']??$this->img_height;
Image::make($path)->resize($width, $height)->save($path);//生成缩略图
}
$ary['path'] = $path;
$ary['ext'] = $type;
return $ary;
}
}
/**
* 上传文件
* @return 已上传文件相关信息
*/
private static function files($request,$dirName)
{
$info = self::getFileInfo($request, $dirName);
//上传文件
if(!Storage::disk('public')->put($info['path'], file_get_contents($info['realPath']))){
abort(201, '上传失败');
}
unset($info['file'], $info['realPath']);
return $info;
}
/**
* 上传图片
* $request 图片信息
* $width 需要缩放宽度
* $height 需要缩放高度
* @return 已上传图片相关信息
**/
private static function imgs($request,$width,$height,$dirName)
{
$info = self::getFileInfo($request,$dirName);
//给图片添加水印功能
// $img = Image::make($info['file'])->resize($width, $height)->insert(self::$watermark,'bottom-right',15,10);
// $img->save($info['path']);
//上传图片
if(!Image::make($info['file'])->resize($width, $height)->save($info['path'])){
abort(201, '上传失败');
}
unset($info['file'], $info['realPath']);
return $info;
}
/**
* 随机的文件名
* @param int $len 随机文件名的长度
* @return str 随机字符串
*/
private static function randName($name)
{
return md5(uniqid($name));
}
/**
* 创建文件上传文件到的路径
* @return str 文件上传的路径
*/
private static function createDir($dirName)
{
$dir = env('UPLOADPATH_FILE') . $dirName. '/'. date('Ymd', time());
if (is_dir($dir) || mkdir($dir, 0777, true)) {
return $dir;
}
}
/**
* 获取上传文件的路径
* @return str 文件的全路径
*/
private static function getUploadPath($originalName, $ext = 'jpg', $dirName)
{
return self::createDir($dirName) . '/' . self::randName($originalName) . '.' . $ext;
}
/**
* 生成上传文件相关信息
* @return 上传文件相关信息
**/
private static function getFileInfo($file, $dirName)
{
// 文件是否上传成功
if ($file->isValid()) {
// 获取文件相关信息
$originalName = $file->getClientOriginalName(); // 文件原名
$ext = $file->getClientOriginalExtension(); // 扩展名
$realPath = $file->getRealPath(); //临时文件的绝对路径
$type = $file->getClientMimeType(); //文件类型
$size = $file->getSize(); //文件大小
$path = self::getUploadPath($originalName, $ext, $dirName);//获取保存的文件路径
return compact('file', 'path', 'ext', 'type', 'size', 'realPath' ,'originalName');
}
return ['code'=>301,'msg'=>'图片上传失败,请重试'];
}
}