UploadService.php 15 KB

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