UploadService.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. <?php
  2. /**
  3. *
  4. * @author: xaboy<365615158@qq.com>
  5. * @day: 2017/10/24
  6. */
  7. namespace service;
  8. use Api\Storage\COS\COS;
  9. use Api\Storage\OSS\OSS;
  10. use Api\Storage\Qiniu\Qiniu;
  11. use app\core\util\SystemConfigService;
  12. class UploadService
  13. {
  14. private static $uploadStatus;
  15. //上传图片的大小 2MB 单位字节
  16. private static $imageValidate = ['size'=>2097152,'ext'=>'jpg,jpeg,png,gif','mime'=>'image/jpeg,image/gif,image/png'];
  17. /**
  18. * 初始化
  19. */
  20. private static function init()
  21. {
  22. self::$uploadStatus = new \StdClass();
  23. }
  24. /**
  25. * 返回失败信息
  26. * @param $error
  27. * @return mixed
  28. */
  29. protected static function setError($error)
  30. {
  31. self::$uploadStatus->status = false;
  32. self::$uploadStatus->error = $error;
  33. return self::$uploadStatus;
  34. }
  35. /**
  36. * 返回成功信息
  37. * @param $path
  38. * @param \think\File $fileInfo
  39. * @return mixed
  40. */
  41. protected static function successful($path, \think\File $fileInfo)
  42. {
  43. $filePath = DS . $path . DS . $fileInfo->getSaveName();
  44. self::$uploadStatus->filePath = self::pathToUrl($filePath);
  45. self::$uploadStatus->fileInfo = $fileInfo;
  46. self::$uploadStatus->uploadPath = $path;
  47. if(strpos(PUBILC_PATH,'public') !== false){
  48. self::$uploadStatus->dir = $filePath;
  49. }else{
  50. self::$uploadStatus->dir = str_replace('/public','',$filePath);
  51. }
  52. self::$uploadStatus->status = true;
  53. return self::$uploadStatus;
  54. }
  55. /**
  56. * 检查上传目录不存在则生成
  57. * @param $dir
  58. * @return bool
  59. */
  60. protected static function validDir($dir)
  61. {
  62. return is_dir($dir) == true || mkdir($dir,0777,true) == true;
  63. }
  64. /**
  65. * 开启/关闭上出文件验证
  66. * @param bool $bool
  67. */
  68. protected static function autoValidate($bool = false)
  69. {
  70. self::$autoValidate = $bool;
  71. }
  72. /**
  73. * 生成上传文件目录
  74. * @param $path
  75. * @param null $root
  76. * @return string
  77. */
  78. protected static function uploadDir($path, $root=null)
  79. {
  80. if($root === null) $root = UPLOAD_PATH;
  81. return $root . DS . $path;
  82. }
  83. /**
  84. * 单图上传
  85. * @param string $fileName 上传文件名
  86. * @param string $path 上传路径
  87. * @param bool $moveName 生成文件名
  88. * @param bool $autoValidate 是否开启文件验证
  89. * @param null $root 上传根目录路径
  90. * @param string $rule 文件名自动生成规则
  91. * @param int $type
  92. * @return mixed
  93. */
  94. public static function image($fileName, $path, $moveName = true, $autoValidate = true, $root = null, $rule='uniqid',$uploadType = null)
  95. {
  96. $uploadType = $uploadType ? $uploadType : SystemConfigService::get('upload_type');
  97. //TODO 没有选择默认使用本地上传
  98. if(!$uploadType) $uploadType = 1;
  99. $info = [];
  100. switch ($uploadType){
  101. case 1 :
  102. self::init();
  103. $path = self::uploadDir($path,$root);
  104. $dir = ROOT_PATH . $path;
  105. if(!self::validDir($dir)) return '生成上传目录失败,请检查权限!';
  106. if(!isset($_FILES[$fileName])) return '上传文件不存在!';
  107. $file = request()->file($fileName);
  108. if($autoValidate) $file = $file->validate(self::$imageValidate);
  109. $fileInfo = $file->rule($rule)->move($dir,$moveName);
  110. if(false === $fileInfo) return self::setError($file->getError());
  111. $imageInfo = self::successful($path,$fileInfo);
  112. $fileInfo = $imageInfo->fileInfo->getinfo();
  113. $info["code"] = 200;
  114. $info["name"] = $imageInfo->fileInfo->getSaveName();
  115. //TODO 入口是public需要替换图片路径
  116. if(strpos(PUBILC_PATH,'public') == false) $imageInfo->dir = str_replace('public/','', $imageInfo->dir);
  117. $info["dir"] = $imageInfo->dir;
  118. $info["time"] = time();
  119. $info["size"] = $fileInfo['size'];
  120. $info["type"] = $fileInfo['type'];
  121. $info["image_type"] = 1;
  122. $info['thumb_path'] = self::thumb($imageInfo->dir);
  123. if(!$imageInfo->status) return $imageInfo->error;
  124. $info["dir"] = strstr($info["dir"],'http') === false ? SystemConfigService::get('site_url').$info["dir"] : $info["dir"];
  125. $info["dir"] = str_replace('\\','/',$info["dir"]);
  126. break;
  127. case 2 :
  128. $keys = Qiniu::uploadImage($fileName);
  129. if(is_array($keys)){
  130. foreach ($keys as $key=>&$item){
  131. if(is_array($item)){
  132. $info = Qiniu::imageUrl($item['key']);
  133. $info['dir'] = UtilService::setHttpType($info['dir']);
  134. $info['thumb_path'] = UtilService::setHttpType($info['thumb_path']);
  135. $headerArray = get_headers(UtilService::setHttpType($info['dir'],1), true);
  136. $info['size'] = is_array($headerArray['Content-Type']) && count($headerArray['Content-Length']) == 2 ? $headerArray['Content-Length'][1] : (string)$headerArray['Content-Length'];
  137. $info['type'] = is_array($headerArray['Content-Type']) && count($headerArray['Content-Type']) == 2 ? $headerArray['Content-Type'][1] : (string)$headerArray['Content-Type'];
  138. $info['image_type'] = 2;
  139. }
  140. }
  141. }else return $keys;
  142. break;
  143. case 3 :
  144. $serverImageInfo = OSS::uploadImage($fileName);
  145. if(!is_array($serverImageInfo)) return $serverImageInfo;
  146. $info['code'] = 200;
  147. $info['name'] = substr(strrchr($serverImageInfo['info']['url'],'/'),1);
  148. $serverImageInfo['info']['url'] = UtilService::setHttpType($serverImageInfo['info']['url']);
  149. $info['dir'] = $serverImageInfo['info']['url'];
  150. $info['thumb_path'] = $serverImageInfo['info']['url'];
  151. $headerArray = get_headers(UtilService::setHttpType($serverImageInfo['info']['url'],1), true);
  152. $info['size'] = $headerArray['Content-Length'];
  153. $info['type'] = $headerArray['Content-Type'];
  154. $info['time'] = time();
  155. $info['image_type'] = 3;
  156. break;
  157. case 4 :
  158. list($imageUrl,$serverImageInfo) = COS::uploadImage($fileName);
  159. if(!is_array($serverImageInfo) && !is_object($serverImageInfo)) return $serverImageInfo;
  160. if(is_object($serverImageInfo)) $serverImageInfo = $serverImageInfo->toArray();
  161. $serverImageInfo['ObjectURL'] = $imageUrl;
  162. $info['code'] = 200;
  163. $info['name'] = substr(strrchr($serverImageInfo['ObjectURL'],'/'),1);
  164. $info['dir'] = $serverImageInfo['ObjectURL'];
  165. $info['thumb_path'] = $serverImageInfo['ObjectURL'];
  166. $headerArray = get_headers(UtilService::setHttpType($serverImageInfo['ObjectURL'],1), true);
  167. $info['size'] = $headerArray['Content-Length'];
  168. $info['type'] = $headerArray['Content-Type'];
  169. $info['time'] = time();
  170. $info['image_type'] = 4;
  171. break;
  172. default: return '上传类型错误,请先选择文件上传类型';
  173. }
  174. return $info;
  175. }
  176. /**
  177. * TODO 单图上传 内容
  178. * @param $key
  179. * @param $content
  180. * @param $path
  181. * @param null $root
  182. * @return array|string
  183. * @throws \Exception
  184. */
  185. public static function imageStream($key, $content, $path, $root = null){
  186. $uploadType = SystemConfigService::get('upload_type');
  187. //TODO 没有选择默认使用本地上传
  188. if(!$uploadType) $uploadType=1;
  189. $siteUrl = SystemConfigService::get('site_url').DS;
  190. $info = [];
  191. stream_context_set_default( [
  192. 'ssl' => [
  193. 'verify_peer' => false,
  194. 'verify_peer_name' => false,
  195. ],
  196. ]);
  197. switch ($uploadType){
  198. case 1 :
  199. self::init();
  200. $path = self::uploadDir($path,$root);
  201. $dir = ROOT_PATH . $path;
  202. if(!self::validDir($dir)) return '生成上传目录失败,请检查权限!';
  203. $name = '.'.DS.$path.DS.$key;
  204. file_put_contents($name,$content);
  205. $info["code"] = 200;
  206. $info["name"] = $key;
  207. //TODO 入口是public需要替换图片路径
  208. if(strpos(PUBILC_PATH,'public') == false) $path = str_replace('public/','', $path);
  209. $info["dir"] = $path.DS.$key;
  210. $info["time"] = time();
  211. $headerArray = get_headers(str_replace('\\','/',UtilService::setHttpType($siteUrl,1).$info['dir']), true);
  212. $info['size'] = $headerArray['Content-Length'];
  213. $info['type'] = $headerArray['Content-Type'];
  214. $info["image_type"] = 1;
  215. $info['thumb_path'] = DS.$info['dir'];
  216. $info['dir'] = DS.$info['dir'];
  217. break;
  218. case 2 :
  219. $keys = Qiniu::uploadImageStream($key,$content);
  220. if(is_array($keys)){
  221. foreach ($keys as $key=>&$item){
  222. if(is_array($item)){
  223. $info = Qiniu::imageUrl($item['key']);
  224. $info['dir'] = UtilService::setHttpType($info['dir']);
  225. $headerArray = get_headers(UtilService::setHttpType(str_replace('\\','/',$info['dir']),1), true);
  226. $info['size'] = $headerArray['Content-Length'];
  227. $info['type'] = $headerArray['Content-Type'];
  228. $info['image_type'] = 2;
  229. }
  230. }
  231. if(!count($info)) return '七牛云文件上传失败';
  232. }else return $keys;
  233. break;
  234. case 3 :
  235. $content = COS::resourceStream($content);
  236. $serverImageInfo = OSS::uploadImageStream($key,$content);
  237. if(!is_array($serverImageInfo)) return $serverImageInfo;
  238. $info['code'] = 200;
  239. $info['name'] = substr(strrchr($serverImageInfo['info']['url'],'/'),1);
  240. $serverImageInfo['info']['url'] = UtilService::setHttpType($serverImageInfo['info']['url']);
  241. $info['dir'] = $serverImageInfo['info']['url'];
  242. $info['thumb_path'] = $serverImageInfo['info']['url'];
  243. $headerArray = get_headers(UtilService::setHttpType(str_replace('\\','/',$serverImageInfo['info']['url']),1), true);
  244. $info['size'] = $headerArray['Content-Length'];
  245. $info['type'] = $headerArray['Content-Type'];
  246. $info['time'] = time();
  247. $info['image_type'] = 3;
  248. break;
  249. case 4 :
  250. list($imageUrl,$serverImageInfo) = COS::uploadImageStream($key,$content);
  251. if(!is_array($serverImageInfo) && !is_object($serverImageInfo)) return $serverImageInfo;
  252. if(is_object($serverImageInfo)) $serverImageInfo = $serverImageInfo->toArray();
  253. $serverImageInfo['ObjectURL'] = $imageUrl;
  254. $info['code'] = 200;
  255. $info['name'] = substr(strrchr($serverImageInfo['ObjectURL'],'/'),1);
  256. $info['dir'] = $serverImageInfo['ObjectURL'];
  257. $info['thumb_path'] = $serverImageInfo['ObjectURL'];
  258. $headerArray = get_headers(UtilService::setHttpType(str_replace('\\','/',$serverImageInfo['ObjectURL']),1), true);
  259. $info['size'] = $headerArray['Content-Length'];
  260. $info['type'] = $headerArray['Content-Type'];
  261. $info['time'] = time();
  262. $info['image_type'] = 4;
  263. break;
  264. default: return '上传类型错误,请先选择文件上传类型';
  265. }
  266. return $info;
  267. }
  268. /**
  269. * 文件上传
  270. * @param string $fileName 上传文件名
  271. * @param string $path 上传路径
  272. * @param bool $moveName 生成文件名
  273. * @param bool $autoValidate 验证规则 [size:1024,ext:[],type:[]]
  274. * @param null $root 上传根目录路径
  275. * @param string $rule 文件名自动生成规则
  276. * @return mixed
  277. */
  278. public static function file($fileName, $path, $moveName = true, $autoValidate=[], $root=null, $rule='uniqid')
  279. {
  280. self::init();
  281. $path = self::uploadDir($path,$root);
  282. $dir = ROOT_PATH . $path;
  283. if(!self::validDir($dir)) return self::setError('生成上传目录失败,请检查权限!');
  284. if(!isset($_FILES[$fileName])) return self::setError('上传文件不存在!');
  285. $extension = strtolower(pathinfo($_FILES[$fileName]['name'], PATHINFO_EXTENSION));
  286. if(strtolower($extension) == 'php' || !$extension)
  287. return self::setError('上传文件非法!');
  288. $file = request()->file($fileName);
  289. if(count($autoValidate)>0) $file = $file->validate($autoValidate);
  290. $fileInfo = $file->rule($rule)->move($dir,$moveName);
  291. if(false === $fileInfo) return self::setError($file->getError());
  292. return self::successful($path,$fileInfo);
  293. }
  294. public static function pathToUrl($path)
  295. {
  296. return trim(str_replace(DS, '/', $path),'.');
  297. }
  298. public static function openImage($filePath)
  299. {
  300. return \think\Image::open($filePath);
  301. }
  302. /**
  303. * 图片压缩
  304. *
  305. * @param string $filePath 文件路径
  306. * @param int $ratio 缩放比例 1-9
  307. * @param string $pre 前缀
  308. * @return string 压缩图片路径
  309. */
  310. public static function thumb($filePath, $ratio=5, $pre='s_')
  311. {
  312. $uname=php_uname('s');
  313. if(strstr($uname,'Windows')!==false) $filePath = ltrim($filePath,'\\');
  314. else $filePath = ltrim($filePath,'/');
  315. $img = self::openImage($filePath);
  316. $width = $img->width() * $ratio / 10;
  317. $height = $img->height() * $ratio / 10;
  318. $dir = dirname($filePath);
  319. $fileName = basename($filePath);
  320. $savePath = $dir.DS.$pre.$fileName;
  321. $img->thumb($width,$height)->save($savePath);
  322. return DS.$savePath;
  323. }
  324. }