UploadFileRepository.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. <?php
  2. /**
  3. * 上传组件
  4. */
  5. namespace App\Repositories;
  6. use App\Repositories\Utils\ImageCryptRepository;
  7. use Carbon\Carbon;
  8. use File;
  9. use Symfony\Component\HttpFoundation\File\UploadedFile;
  10. use Intervention\Image\Facades\Image;
  11. class UploadFileRepository
  12. {
  13. private $caesarOffset = 5; // 凯撒偏移量
  14. private $serverNo = '001';
  15. private $uploadFileInfo = array(); //上传文件信息
  16. private $tmpPath; //临时本地保存目录
  17. private $tmpChunkDir = 'chunk'; //临时本地分块文件保存目录
  18. private $saveRelativePath = ''; //保存相对路径
  19. private $picExt = array('jpg', 'gif', 'png', 'jpeg'); //图像扩展名
  20. public $urlBase = ''; //url基地址
  21. public $maxSize = -1; //最大尺寸
  22. public $allowExt = array(); //允许的扩展名
  23. public $allowMime = array(); //允许的MIME
  24. public $thumb = false; //是否缩略图
  25. public $thumbMaxWidth = array(); //缩略图最大宽度
  26. public $thumbMaxHeight = array(); //缩略图最大高度
  27. public $thumbAppointed = array(); //是否固定宽高大小
  28. public $thumbWater = array(); //是否水印
  29. public $thumbPath = array(); //缩略图保存路径
  30. public $thumbFileName = array(); //缩略图文件名
  31. public $thumbPrefix = ''; //缩略图前缀
  32. public $thumbSuffix = ''; //缩略图后缀
  33. public $waterType = 'picture'; //水印类型
  34. public $waterPicture = ''; //水印图片路径
  35. public $waterText = ''; //水印文字
  36. public $waterFont = ''; //水印文字字体
  37. public $waterColor = ''; //水印文字颜色
  38. public $waterPosition = 9; //水印位置
  39. public $subDir = ''; //子目录
  40. public $savePath = ''; //保存路径
  41. public $renameRule = ''; //保存重命名规则
  42. public $dirDateFormat = 'Ym'; //目录时间格式
  43. public $unlinkOriginPic = true; //是否删除原图
  44. public $saveRootPath = ''; //保存服务器跟目录
  45. public $saveRemote = false; //是否远程保存
  46. public $remoteServer = array(); //远程服务器信息
  47. private $error = ''; //错误信息
  48. private $isEncode = false; // 是否加密.
  49. /**
  50. * 图片加密仓库.
  51. * @var null|ImageCryptRepository
  52. */
  53. private $imageRepo = null;
  54. /**
  55. * 构造函数
  56. * @param string $maxSize 最大尺寸
  57. * @param array $allowExt 允许的扩展名
  58. * @param array $allowMime 允许的mime
  59. * @param string $savePath 保存路径
  60. * @param string $saveRootPath 保存服务器跟目录
  61. * @param string $renameRule 重命名规则
  62. */
  63. public function __construct(
  64. $maxSize = '',
  65. $allowExt = array(),
  66. $allowMime = array(),
  67. $savePath = '',
  68. $saveRootPath = '',
  69. $renameRule = ''
  70. ) {
  71. $this->reset();
  72. $this->urlBase = '';
  73. if (!empty($maxSize) && is_numeric($maxSize)) {
  74. $this->maxSize = $maxSize;
  75. }
  76. if ($allowExt) {
  77. if (is_array($allowExt)) {
  78. $this->allowExt = array_map('strtolower', $allowExt);
  79. } else {
  80. $this->allowExt = explode(',', strtolower($allowExt));
  81. }
  82. }
  83. if ($allowMime) {
  84. if (is_array($allowMime)) {
  85. $this->allowMime = $allowMime;
  86. } else {
  87. $this->allowMime = explode(',', $allowMime);
  88. }
  89. }
  90. if ($savePath != '') {
  91. $this->savePath = $savePath;
  92. } else {
  93. $this->savePath = '';
  94. }
  95. if ($saveRootPath) {
  96. $this->saveRootPath = rtrim($saveRootPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
  97. }
  98. if ($renameRule) {
  99. $this->renameRule = $renameRule;
  100. }
  101. $imageServersConf = config('image_servers');
  102. $isEncode = $imageServersConf['servers'][$imageServersConf['upload_server_no']]['is_encode'] ?? false;
  103. $this->isEncode = $isEncode;
  104. $this->setServerNo($imageServersConf['upload_server_no']);
  105. }
  106. public function setServerNo($number)
  107. {
  108. $this->serverNo = str_pad((string)$number, 3, '0', STR_PAD_LEFT);
  109. }
  110. public function getServerNo()
  111. {
  112. return $this->serverNo;
  113. }
  114. public function setIsEncode($isEncode)
  115. {
  116. $this->isEncode = $isEncode;
  117. }
  118. public function getIsEncode()
  119. {
  120. return $this->isEncode;
  121. }
  122. /**
  123. * 重设参数
  124. */
  125. public function reset()
  126. {
  127. $this->urlBase = '';
  128. $this->maxSize = -1;
  129. $this->allowExt = array();
  130. $this->savePath = '';
  131. $this->thumb = false;
  132. $this->thumbMaxWidth = array();
  133. $this->thumbMaxHeight = array();
  134. $this->thumbAppointed = array();
  135. $this->thumbWater = array();
  136. $this->thumbPath = array();
  137. $this->thumbFileName = array();
  138. $this->thumbPrefix = 't_';
  139. $this->thumbSuffix = '';
  140. $this->waterType = 'picture';
  141. $this->waterPicture = '';
  142. $this->waterText = '';
  143. $this->waterFont = '';
  144. $this->waterColor = '';
  145. $this->waterPosition = '';
  146. $this->subDir = '';
  147. $this->savePath = '';
  148. $this->dirDateFormat = 'Ym';
  149. $this->renameRule = '';
  150. $this->saveRootPath = '';
  151. $this->saveRemote = false;
  152. $this->remoteServer = array();
  153. $this->error = '';
  154. $this->unlinkOriginPic = true;
  155. }
  156. /**
  157. * 保存
  158. * @param UploadedFile $file 文件对象
  159. * @param string $save_dir 保存路径
  160. * @return array|bool
  161. */
  162. private function save($file, $save_dir)
  163. {
  164. $arr_return = array();
  165. $file_ext = strtolower($file->getClientOriginalExtension());
  166. $file_mime = $file->getMimeType();
  167. $file_origin_name = $file->getClientOriginalName();
  168. $file_base_name = $file->getBasename('.' . $file_ext);
  169. $arr_file_names = $this->getSaveName($file);
  170. $file_name = $arr_file_names['save_name'];
  171. $file_origin_tmp_name = $arr_file_names['save_origin_name'];
  172. $file_old_size = $file->getSize();
  173. $is_pic = false;
  174. if (in_array($file_ext, array('gif', 'jpg', 'jpeg', 'png', 'swf'))
  175. && false === getimagesize($file->getPathname())) {
  176. $this->error = '非法图像文件';
  177. return false;
  178. }
  179. $file->move($save_dir, $file_origin_tmp_name);
  180. $file_native_path = $save_dir . $file_origin_tmp_name;
  181. if (in_array($file_ext, $this->picExt)) {
  182. // 图片类
  183. $is_pic = true;
  184. if ($this->thumb) {
  185. $native_image = getimagesize($file_native_path);
  186. if (false !== $native_image) {
  187. $water_limit_width = 300;
  188. $water_limit_height = 300;
  189. $water_pic_width = $water_pic_height = 0;
  190. if ($this->waterType == 'picture' && !empty($this->waterPicture)) {
  191. $arr_water_pic_position = array(
  192. '1' => 'top-left',
  193. '2' => 'top',
  194. '3' => 'top-right',
  195. '4' => 'left',
  196. '5' => 'center',
  197. '6' => 'right',
  198. '7' => 'bottom-left',
  199. '8' => 'bottom',
  200. '9' => 'bottom-right'
  201. );
  202. if ($this->waterPosition >= 1 && $this->waterPosition <= 9) {
  203. $water_pic_position = $arr_water_pic_position[$this->waterPosition];
  204. } else {
  205. $water_rand_key = mt_rand(1, 9);
  206. $water_pic_position = $arr_water_pic_position[$water_rand_key];
  207. }
  208. $water_image = getimagesize($this->waterPicture);
  209. if ($water_image !== false) {
  210. $water_pic_width = $water_image[0];
  211. $water_pic_height = $water_image[1];
  212. if ($water_pic_width) {
  213. $water_limit_width = $water_pic_width * 2;
  214. }
  215. if ($water_pic_height) {
  216. $water_limit_height = $water_pic_height * 2;
  217. }
  218. }
  219. }
  220. $count_thumb = count($this->thumbMaxWidth);
  221. for ($i = 0, $len = $count_thumb; $i < $len; $i++) {
  222. $img = null;
  223. $arr_img_path = $arr_img_relative_path = array();
  224. $name_prefix = $count_thumb > 1 ? $this->thumbPrefix : '';
  225. $name_suffix = $count_thumb > 1 ? $this->thumbSuffix : '';
  226. $name_suffix_new = $count_thumb > 1 ? $name_suffix . '_' . ($i + 1) : $name_suffix;
  227. $fileThumbBaseNameNoExt = $name_prefix . substr($file_name, 0, strrpos($file_name, '.'))
  228. . $name_suffix_new;
  229. $file_thumb_bame = $fileThumbBaseNameNoExt . '.' . $file_ext;
  230. $arr_img_path[$i] = $save_dir . $file_thumb_bame;
  231. $arr_img_relative_path[$i] = $this->saveRelativePath . $file_thumb_bame;
  232. $tmp_file_path = $save_dir . 'tmp_' . $i . '_' . $file_name;
  233. File::copy($file_native_path, $tmp_file_path);
  234. if ($this->thumbMaxWidth[$i] > 0 && $this->thumbMaxHeight[$i] > 0) {
  235. if ($this->thumbAppointed[$i]) {
  236. $img = Image::make($tmp_file_path)->resize(
  237. $this->thumbMaxWidth[$i],
  238. $this->thumbMaxHeight[$i],
  239. function ($constraint) {
  240. $constraint->upsize();
  241. }
  242. );
  243. } else {
  244. $img = Image::make($tmp_file_path)->resize(
  245. $this->thumbMaxWidth[$i],
  246. $this->thumbMaxHeight[$i],
  247. function ($constraint) {
  248. $constraint->aspectRatio();
  249. }
  250. );
  251. }
  252. } else {
  253. $img = Image::make($tmp_file_path);
  254. }
  255. if ($this->thumbWater[$i] && $this->waterType == 'picture' && !empty($this->waterPicture)) {
  256. $native_thumb_image = getimagesize($tmp_file_path);
  257. if ($native_thumb_image[0] > $water_limit_width
  258. && $native_thumb_image[1] > $water_limit_height) {
  259. $img->insert($this->waterPicture, 0, 0, $water_pic_position);
  260. }
  261. }
  262. $img->save($arr_img_path[$i]);
  263. $file_thumb_size = File::size($arr_img_path[$i]);
  264. $thumb_native_image = getimagesize($arr_img_path[$i]);
  265. $thumb_native_width = $thumb_native_image[0];
  266. $thumb_native_height = $thumb_native_image[1];
  267. File::delete($tmp_file_path);
  268. if ($this->isEncode) {
  269. $fileEncodePath = $fileThumbBaseNameNoExt . '.ceb';
  270. $encodeSavePath = $save_dir . $fileEncodePath;
  271. $this->getImageRepo()->encode(file_get_contents($arr_img_path[$i]), $encodeSavePath);
  272. $arr_img_relative_path[$i] = $this->saveRelativePath . $fileEncodePath;
  273. File::delete($arr_img_path[$i]); // 删除未加密的图
  274. }
  275. $arr_temp = array(
  276. 'file_origin_name' => $file_origin_name,
  277. 'file_name' => $file_thumb_bame,
  278. 'file_size' => $file_thumb_size,
  279. 'file_path' => $arr_img_relative_path[$i],
  280. 'file_ext' => $file_ext,
  281. 'file_mime' => $file_mime,
  282. 'width' => $thumb_native_width,
  283. 'height' => $thumb_native_height,
  284. 'link_url' => $this->urlBase . $arr_img_relative_path[$i],
  285. 'is_pic' => 1,
  286. 'origin_pic_relative_path' => $this->saveRelativePath . $file_origin_tmp_name,
  287. 'origin_pic_native_path' => $file_native_path, //返回本地原图
  288. 'origin_pic_size' => $file_old_size,
  289. 'origin_pic_name' => $file_origin_tmp_name,
  290. 'origin_pic_width' => $native_image[0],
  291. 'origin_pic_height' => $native_image[1],
  292. 'file_native_path' => $save_dir . $file_thumb_bame,
  293. );
  294. $arr_return[] = $arr_temp;
  295. $img->destroy();
  296. }
  297. if ($this->unlinkOriginPic == true) {
  298. File::delete($file_native_path); //删除本地原图
  299. }
  300. }
  301. } else {
  302. // 不裁剪或者水印
  303. $fileNameNoExt = substr($file_name, 0, strrpos($file_name, '.'));
  304. $file_relative_path = $this->saveRelativePath . $file_name;
  305. $saveNewPath = $save_dir. $file_name;
  306. @rename($file_native_path, $saveNewPath);
  307. if ($this->isEncode) {
  308. $fileEncodePath = $fileNameNoExt . '.ceb';
  309. $encodeSavePath = $save_dir . $fileEncodePath;
  310. $this->getImageRepo()->encode(file_get_contents($saveNewPath), $encodeSavePath);
  311. $file_relative_path = $this->saveRelativePath . $fileEncodePath;
  312. File::delete($saveNewPath); // 删除未加密的图
  313. }
  314. $arr_temp = array(
  315. 'file_origin_name' => $file_origin_name,
  316. 'file_name' => $file_name,
  317. 'file_size' => $file_old_size,
  318. 'file_path' => $file_relative_path,
  319. 'file_ext' => $file_ext,
  320. 'file_mime' => $file_mime,
  321. 'width' => 0,
  322. 'height' => 0,
  323. 'link_url' => $this->urlBase . $file_relative_path,
  324. 'is_pic' => 1,
  325. 'origin_pic_relative_path' => '',
  326. 'origin_pic_native_path' => '', //返回本地原图
  327. 'origin_pic_size' => '',
  328. 'origin_pic_name' => '',
  329. 'origin_pic_width' => 0,
  330. 'origin_pic_height' => 0,
  331. 'file_native_path' => $save_dir . $file_name,
  332. );
  333. $arr_return[] = $arr_temp;
  334. }
  335. } else {
  336. // 非图片类.
  337. $file_relative_path = $this->saveRelativePath . $file_name;
  338. @rename($save_dir . $file_origin_tmp_name, $save_dir . $file_name);
  339. $arr_temp = array(
  340. 'file_origin_name' => $file_origin_name,
  341. 'file_name' => $file_name,
  342. 'file_size' => $file_old_size,
  343. 'file_path' => $file_relative_path,
  344. 'file_ext' => $file_ext,
  345. 'file_mime' => $file_mime,
  346. 'width' => 0,
  347. 'height' => 0,
  348. 'link_url' => $this->urlBase . $file_relative_path,
  349. 'is_pic' => 0,
  350. 'origin_pic_relative_path' => '',
  351. 'origin_pic_native_path' => '', //返回本地原图
  352. 'origin_pic_size' => '',
  353. 'origin_pic_name' => '',
  354. 'origin_pic_width' => 0,
  355. 'origin_pic_height' => 0,
  356. 'file_native_path' => $save_dir . $file_name,
  357. );
  358. $arr_return[] = $arr_temp;
  359. }
  360. return $arr_return;
  361. }
  362. /**
  363. * 获得保存的目录
  364. * @return string
  365. */
  366. private function getSaveDir()
  367. {
  368. $dir = '';
  369. if (!empty($this->savePath) && $this->savePath != '/') {
  370. $dir = trim($this->savePath, '/') . '/';
  371. }
  372. $dir .= $this->getServerNo() . '/';
  373. if (!empty($this->subDir) && $this->subDir != '/') {
  374. $dir .= trim($this->subDir, '/') . '/';
  375. }
  376. $dateEncodeName = caesar_encode(Carbon::now()->format($this->dirDateFormat), '', $this->caesarOffset);
  377. $dir_date = $dateEncodeName . '/';
  378. $dir .= $dir_date;
  379. $this->saveRelativePath = $dir;
  380. $dir = $this->saveRootPath . $dir;
  381. if (!File::isDirectory($dir)) {
  382. File::makeDirectory($dir, 0777, true, true);
  383. }
  384. return $dir;
  385. }
  386. /**
  387. * 开始上传
  388. * @param string $file_field 文件域
  389. * @return bool|array
  390. */
  391. public function upload($file_field)
  392. {
  393. $request = request();
  394. $save_dir = $this->getSaveDir();
  395. $file_info = array();
  396. if ($request->exists('chunk') && $request->exists('chunks')) {
  397. $result = self::chunkInputSave($file_field);
  398. if ($result != false) {
  399. $file_info[] = $result;
  400. } else {
  401. return false;
  402. }
  403. } else {
  404. if ($request->hasFile($file_field)) {
  405. $files = $this->dealFiles($file_field);
  406. foreach ($files as $key => $file) {
  407. /**
  408. * @var UploadedFile $file
  409. */
  410. if (!$this->check($file)) {
  411. return false;
  412. }
  413. if ($file->getClientOriginalName()) { //$_FILES['xxx']['name']
  414. if ($request->exists('name') && $request->exists('chunk') && $request->exists('chunks')) {
  415. $result = self::chunkInputSave($file_field);
  416. } else {
  417. $result = $this->save($file, $save_dir);
  418. }
  419. if ($result) {
  420. $file_info[] = $result;
  421. } else {
  422. return false;
  423. }
  424. }
  425. }
  426. } else {
  427. $this->error = '非法请求';
  428. return false;
  429. }
  430. }
  431. if ($file_info) {
  432. $this->uploadFileInfo = $file_info;
  433. return true;
  434. } else {
  435. $this->error = '没有选择上传文件';
  436. return false;
  437. }
  438. }
  439. public function getResultFileInfo()
  440. {
  441. return $this->uploadFileInfo ? $this->uploadFileInfo : array();
  442. }
  443. public function getResultError()
  444. {
  445. return $this->error ? $this->error : '';
  446. }
  447. private function chunkInputSave($file_field)
  448. {
  449. $request = request();
  450. if ($request->getMethod() != 'POST') {
  451. $this->error = '请求无效';
  452. return false;
  453. }
  454. if (!($request->exists('chunk') && $request->exists('chunks'))) {
  455. $this->error = '请求无效';
  456. return false;
  457. }
  458. if ($request->exists('name')) {
  459. $file_origin_name = $file_name = trim($request->get('name', ''));
  460. } elseif ($request->hasFile($file_field)) {
  461. $file_origin_name = $file_name = $_FILES[$file_field]['name'];
  462. } else {
  463. $file_origin_name = $file_name = uniqid('tmp_ck_');
  464. }
  465. $file_name = md5($file_name);
  466. $chunk = intval($request->get('chunk', 0));
  467. $chunks = intval($request->get('chunks', 0));
  468. $arr_return = array();
  469. $arr_file_info = array();
  470. $is_pic = 0;
  471. $width = 0;
  472. $height = 0;
  473. $file_size = 0;
  474. $file_ext = file_ext($file_origin_name); //扩展名
  475. if (!self::checkMime($file_ext)) {
  476. $this->error = '上传文件MIME类型不允许!';
  477. return false;
  478. }
  479. if (!self::checkExtension($file_ext)) {
  480. $this->error = '上传文件类型不允许';
  481. return false;
  482. }
  483. $arr_mimes = include(storage_path('app/data') . DIRECTORY_SEPARATOR . 'mime.php');
  484. $file_mime = isset($arr_mimes[$file_ext]) ? $arr_mimes[$file_ext] : 'text/plain'; //文件MIME
  485. $tmp_save_path = storage_path('data') . DIRECTORY_SEPARATOR . $this->tmpChunkDir; //临时保存目录路径
  486. //临时文件不存在则强制创建
  487. if (!File::exists($tmp_save_path)) {
  488. File::makeDirectory($tmp_save_path, 0777, true, true);
  489. }
  490. $tmp_file_name = $file_name . '.part'; //临时文件名
  491. $tmp_file_path = $tmp_save_path . DIRECTORY_SEPARATOR . $tmp_file_name; //完整临时文件路径
  492. $file_tmp_full_name = 'ck_' . $file_origin_name;
  493. $file_tmp_path = $tmp_save_path . DIRECTORY_SEPARATOR . $tmp_file_name;
  494. //清理过期分块文件
  495. self::chunkCleanupDir($file_tmp_path);
  496. $err_msg = '';
  497. if ($out = @fopen($file_tmp_path, $chunk ? 'ab' : 'wb')) {
  498. if ($request->hasFile($file_field)) {
  499. $in = @fopen($_FILES[$file_field]["tmp_name"], "rb");
  500. } else {
  501. $in = @fopen("php://input", 'rb');
  502. }
  503. if ($in) {
  504. while ($buff = fread($in, 4096)) {
  505. fwrite($out, $buff);
  506. }
  507. } else {
  508. $err_msg = '无法读取文件';
  509. }
  510. @fclose($in);
  511. } else {
  512. $err_msg = '无法打开文件';
  513. }
  514. @fclose($out);
  515. if ($err_msg) {
  516. $this->error = $err_msg;
  517. return false;
  518. }
  519. if (empty($chunks) || $chunk == $chunks - 1) {
  520. $save_dir = $this->getSaveDir(); //保存目录路径
  521. $rd_name = self::makeFileTimeName(); //产生一个随机文件名
  522. $file_full_name = 'ck_' . $rd_name . '.' . $file_ext;
  523. $file_path = $save_dir . DIRECTORY_SEPARATOR . $file_full_name;
  524. $file_relative_path = $this->saveRelativePath . $file_full_name;
  525. if (!File::move($file_tmp_path, $file_path)) {
  526. $this->error = '无法移动文件';
  527. return false;
  528. }
  529. $file_size = File::size($file_path); //获取文件大小
  530. if (in_array($file_ext, array('jpg', 'jpeg', 'gif', 'png', 'psd'))) {
  531. $is_pic = 1;
  532. $img = getimagesize($file_path);
  533. if ($img !== false) {
  534. $width = $img[0];
  535. $height = $img[1];
  536. }
  537. }
  538. $arr_file_info = array(
  539. 'file_origin_name' => $file_origin_name,
  540. 'file_name' => $file_full_name,
  541. 'file_size' => $file_size,
  542. 'file_path' => $file_relative_path,
  543. 'file_ext' => $file_ext,
  544. 'file_mime' => $file_mime,
  545. 'width' => $width,
  546. 'height' => $height,
  547. 'link_url' => $this->urlBase . $file_relative_path,
  548. 'is_pic' => $is_pic,
  549. 'origin_pic_relative_path' => $file_relative_path,
  550. 'origin_pic_native_path' => $file_path, //返回本地原图
  551. );
  552. }
  553. $arr_return[] = $arr_file_info;
  554. return $arr_return;
  555. }
  556. private function chunkCleanupDir($file_path)
  557. {
  558. $max_file_age = 5 * 60 * 60; //5小时
  559. $tmp_save_path = storage_path('app/data') . DIRECTORY_SEPARATOR . $this->tmpChunkDir;
  560. $dir = opendir($tmp_save_path);
  561. if ($dir) {
  562. $now_time = Carbon::now()->timestamp;
  563. while (($file = readdir($dir)) !== false) {
  564. $tmp_file_path = $tmp_save_path . DIRECTORY_SEPARATOR . $file;
  565. if ($tmp_file_path == $file_path) {
  566. continue;
  567. }
  568. if (preg_match('/\.part$/', $file) && filemtime($tmp_file_path) < $now_time - $max_file_age) {
  569. File::delete($tmp_file_path);
  570. }
  571. }
  572. }
  573. closedir($dir);
  574. }
  575. /**
  576. * 分配多文件上传
  577. * @param string $file_field 上传域
  578. * @return array
  579. */
  580. private function dealFiles($file_field)
  581. {
  582. $request = request();
  583. $arr_files = array();
  584. if (is_array($request->file($file_field))) {
  585. foreach ($request->file($file_field) as $file) {
  586. $arr_files[] = $file;
  587. }
  588. } else {
  589. $arr_files[] = $request->file($file_field);
  590. }
  591. return $arr_files;
  592. }
  593. /**
  594. * 获取保存后的文件名,不包含扩展名
  595. * @param UploadedFile $file 文件对象
  596. * @return array
  597. */
  598. private function getSaveName($file)
  599. {
  600. $rd_name = self::makeFileTimeName();
  601. $r = array(
  602. 'save_name' => '',
  603. 'save_origin_name' => '',
  604. );
  605. if (empty($this->renameRule)) {
  606. $save_name = $rd_name . '.' . $file->getClientOriginalExtension();
  607. } else {
  608. if (method_exists($this, $this->renameRule)) {
  609. $rule_name = $this->renameRule;
  610. $rd_name = $rule_name();
  611. } else {
  612. $save_name = self::makeFileTimeName() . '.' . $file->getClientOriginalExtension();
  613. }
  614. }
  615. return array(
  616. 'save_name' => $rd_name . '.' . $file->getClientOriginalExtension(),
  617. 'save_origin_name' => 'original_' . $rd_name . '.' . $file->getClientOriginalExtension(),
  618. );
  619. }
  620. /**
  621. * 产生一个时间格式的文件名
  622. * @return string
  623. */
  624. private function makeFileTimeName()
  625. {
  626. $dateDir = caesar_encode(Carbon::now()->format('Ymd'), '', $this->caesarOffset);
  627. return $this->getServerNo() . rand_str(9);
  628. }
  629. /**
  630. * 常规检查
  631. * @param UploadedFile $file 文件对象
  632. * @return bool
  633. */
  634. private function check($file)
  635. {
  636. if ($file->getError()) {
  637. $this->error = $file->getError();
  638. return false;
  639. }
  640. if (!self::checkMime($file->getMimeType())) {
  641. $this->error = '上传文件MIME类型不允许!';
  642. return false;
  643. }
  644. if (!self::checkExtension($file->getClientOriginalExtension())) {
  645. $this->error = '上传文件类型不允许';
  646. return false;
  647. }
  648. if (!self::checkSize($file->getSize())) {
  649. $this->error = '上传文件大小超出限制!';
  650. return false;
  651. }
  652. return true;
  653. }
  654. /**
  655. * 检查MIME
  656. * @param string $mime Mime
  657. * @return bool
  658. */
  659. private function checkMime($mime)
  660. {
  661. if ($this->allowMime) {
  662. return in_array($mime, $this->allowMime);
  663. } else {
  664. return true;
  665. }
  666. }
  667. /**
  668. * 检查扩展名
  669. * @param string $ext 扩展名
  670. * @return bool
  671. */
  672. private function checkExtension($ext)
  673. {
  674. if ($this->allowExt) {
  675. return in_array($ext, $this->allowExt);
  676. } else {
  677. return true;
  678. }
  679. }
  680. /**
  681. * 检查尺寸
  682. * @param int $size 尺寸大小
  683. * @return bool
  684. */
  685. private function checkSize($size)
  686. {
  687. return !($size > $this->maxSize) || (-1 == $this->maxSize);
  688. }
  689. /**
  690. * 获取图像仓库.
  691. * @return ImageCryptRepository
  692. */
  693. private function getImageRepo()
  694. {
  695. if (!$this->imageRepo instanceof ImageCryptRepository) {
  696. $this->imageRepo = new ImageCryptRepository();
  697. }
  698. return $this->imageRepo;
  699. }
  700. }