FileService.php 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: pengyong <i@pengyong.info>
  10. // +----------------------------------------------------------------------
  11. namespace crmeb\services;
  12. /**
  13. * 文件操作类
  14. * Class FileService
  15. * @package crmeb\services
  16. */
  17. class FileService
  18. {
  19. /**
  20. * 创建目录
  21. * @param string $dir
  22. * @return bool
  23. */
  24. public static function mkDir(string $dir)
  25. {
  26. $dir = rtrim($dir, '/') . '/';
  27. if (!is_dir($dir)) {
  28. if (mkdir($dir, 0700) == false) {
  29. return false;
  30. }
  31. return true;
  32. }
  33. return true;
  34. }
  35. /**
  36. * @param $filename 写入文件名
  37. * @param $writetext 保存内容
  38. * @param string $openmod 打开方式
  39. * @return bool
  40. */
  41. public static function writeFile(string $filename, string $writetext, string $openmod = 'w')
  42. {
  43. if (@$fp = fopen($filename, $openmod)) {
  44. flock($fp, 2);
  45. fwrite($fp, $writetext);
  46. fclose($fp);
  47. return true;
  48. } else {
  49. return false;
  50. }
  51. }
  52. /**
  53. * 删除目录下所有满足条件文件
  54. * @param $path 文件目录
  55. * @param $start 开始时间
  56. * @param $end 结束时间
  57. * return bool
  58. */
  59. public static function del_where_dir($path,$start = '',$end = '')
  60. {
  61. if(!file_exists($path)){
  62. return false;
  63. }
  64. $dh = @opendir($path);
  65. if($dh){
  66. while(($d = readdir($dh)) !== false){
  67. if($d == '.' || $d == '..'){//如果为.或..
  68. continue;
  69. }
  70. $tmp = $path.'/'.$d;
  71. if(!is_dir($tmp) ){//如果为文件
  72. $file_time = filemtime($tmp);
  73. if($file_time){
  74. if($start != '' && $end != ''){
  75. if($file_time >= $start && $file_time <= $end){
  76. @unlink($tmp);
  77. }
  78. }elseif($start != '' && $end == ''){
  79. if($file_time >= $start ){
  80. @unlink($tmp);
  81. }
  82. }elseif($start == '' && $end != ''){
  83. if($file_time <= $end){
  84. @unlink($tmp);
  85. }
  86. }else{
  87. @unlink($tmp);
  88. }
  89. }
  90. }else{//如果为目录
  91. self::delDir($tmp,$start,$end);
  92. }
  93. }
  94. //判断文件夹下是否 还有文件
  95. $count = count(scandir($path));
  96. closedir($dh);
  97. if($count <= 2) @rmdir($path);
  98. }
  99. return true;
  100. }
  101. /**
  102. * 删除目录
  103. * @param $dirName
  104. * @return bool
  105. */
  106. public static function delDir($dirName)
  107. {
  108. if (!file_exists($dirName)) {
  109. return false;
  110. }
  111. $dir = opendir($dirName);
  112. while ($fileName = readdir($dir)) {
  113. $file = $dirName . '/' . $fileName;
  114. if ($fileName != '.' && $fileName != '..') {
  115. if (is_dir($file)) {
  116. self::delDir($file);
  117. } else {
  118. unlink($file);
  119. }
  120. }
  121. }
  122. closedir($dir);
  123. return rmdir($dirName);
  124. }
  125. /**
  126. * 拷贝目录
  127. * @param string $surDir
  128. * @param string $toDir
  129. * @return bool
  130. */
  131. public function copyDir(string $surDir, string $toDir)
  132. {
  133. $surDir = rtrim($surDir, '/') . '/';
  134. $toDir = rtrim($toDir, '/') . '/';
  135. if (!file_exists($surDir)) {
  136. return false;
  137. }
  138. if (!file_exists($toDir)) {
  139. $this->createDir($toDir);
  140. }
  141. $file = opendir($surDir);
  142. while ($fileName = readdir($file)) {
  143. $file1 = $surDir . '/' . $fileName;
  144. $file2 = $toDir . '/' . $fileName;
  145. if ($fileName != '.' && $fileName != '..') {
  146. if (is_dir($file1)) {
  147. self::copy_dir($file1, $file2);
  148. } else {
  149. copy($file1, $file2);
  150. }
  151. }
  152. }
  153. closedir($file);
  154. return true;
  155. }
  156. /**
  157. * 列出目录
  158. * @param $dir 目录名
  159. * @return array 列出文件夹下内容,返回数组 $dirArray['dir']:存文件夹;$dirArray['file']:存文件
  160. */
  161. static function getDirs($dir)
  162. {
  163. $dir = rtrim($dir, '/') . '/';
  164. $dirArray [][] = NULL;
  165. if (false != ($handle = opendir($dir))) {
  166. $i = 0;
  167. $j = 0;
  168. while (false !== ($file = readdir($handle))) {
  169. if (is_dir($dir . $file)) { //判断是否文件夹
  170. $dirArray ['dir'] [$i] = $file;
  171. $i++;
  172. } else {
  173. $dirArray ['file'] [$j] = $file;
  174. $j++;
  175. }
  176. }
  177. closedir($handle);
  178. }
  179. return $dirArray;
  180. }
  181. /**
  182. * 统计文件夹大小
  183. * @param $dir
  184. * @return int 文件夹大小(单位 B)
  185. */
  186. public static function getSize($dir)
  187. {
  188. $dirlist = opendir($dir);
  189. $dirsize = 0;
  190. while (false !== ($folderorfile = readdir($dirlist))) {
  191. if ($folderorfile != "." && $folderorfile != "..") {
  192. if (is_dir("$dir/$folderorfile")) {
  193. $dirsize += self::getSize("$dir/$folderorfile");
  194. } else {
  195. $dirsize += filesize("$dir/$folderorfile");
  196. }
  197. }
  198. }
  199. closedir($dirlist);
  200. return $dirsize;
  201. }
  202. /**
  203. * 检测是否为空文件夹
  204. * @param $dir
  205. * @return bool
  206. */
  207. static function emptyDir($dir)
  208. {
  209. return (($files = @scandir($dir)) && count($files) <= 2);
  210. }
  211. /**
  212. * 创建多级目录
  213. * @param string $dir
  214. * @param int $mode
  215. * @return boolean
  216. */
  217. public function createDir(string $dir, int $mode = 0777)
  218. {
  219. return is_dir($dir) or ($this->createDir(dirname($dir)) and mkdir($dir, $mode));
  220. }
  221. /**
  222. * 创建指定路径下的指定文件
  223. * @param string $path (需要包含文件名和后缀)
  224. * @param boolean $over_write 是否覆盖文件
  225. * @param int $time 设置时间。默认是当前系统时间
  226. * @param int $atime 设置访问时间。默认是当前系统时间
  227. * @return boolean
  228. */
  229. public function createFile(string $path, bool $over_write = FALSE, int $time = NULL, int $atime = NULL)
  230. {
  231. $path = $this->dirReplace($path);
  232. $time = empty($time) ? time() : $time;
  233. $atime = empty($atime) ? time() : $atime;
  234. if (file_exists($path) && $over_write) {
  235. $this->unlinkFile($path);
  236. }
  237. $aimDir = dirname($path);
  238. $this->createDir($aimDir);
  239. return touch($path, $time, $atime);
  240. }
  241. /**
  242. * 关闭文件操作
  243. * @param string $path
  244. * @return boolean
  245. */
  246. public function close(string $path)
  247. {
  248. return fclose($path);
  249. }
  250. /**
  251. * 读取文件操作
  252. * @param string $file
  253. * @return boolean
  254. */
  255. public static function readFile(string $file)
  256. {
  257. return @file_get_contents($file);
  258. }
  259. /**
  260. * 确定服务器的最大上传限制(字节数)
  261. * @return int 服务器允许的最大上传字节数
  262. */
  263. public function allowUploadSize()
  264. {
  265. $val = trim(ini_get('upload_max_filesize'));
  266. return $val;
  267. }
  268. /**
  269. * 字节格式化 把字节数格式为 B K M G T P E Z Y 描述的大小
  270. * @param int $size 大小
  271. * @param int $dec 显示类型
  272. * @return int
  273. */
  274. public static function byteFormat($size, $dec = 2)
  275. {
  276. $a = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
  277. $pos = 0;
  278. while ($size >= 1024) {
  279. $size /= 1024;
  280. $pos++;
  281. }
  282. return round($size, $dec) . " " . $a[$pos];
  283. }
  284. /**
  285. * 删除非空目录
  286. * 说明:只能删除非系统和特定权限的文件,否则会出现错误
  287. * @param string $dirName 目录路径
  288. * @param boolean $is_all 是否删除所有
  289. * @param boolean $delDir 是否删除目录
  290. * @return boolean
  291. */
  292. public function removeDir(str $dir_path, bool $is_all = FALSE)
  293. {
  294. $dirName = $this->dirReplace($dir_path);
  295. $handle = @opendir($dirName);
  296. while (($file = @readdir($handle)) !== FALSE) {
  297. if ($file != '.' && $file != '..') {
  298. $dir = $dirName . '/' . $file;
  299. if ($is_all) {
  300. is_dir($dir) ? $this->removeDir($dir) : $this->unlinkFile($dir);
  301. } else {
  302. if (is_file($dir)) {
  303. $this->unlinkFile($dir);
  304. }
  305. }
  306. }
  307. }
  308. closedir($handle);
  309. return @rmdir($dirName);
  310. }
  311. /**
  312. * 获取完整文件名
  313. * @param string $fn 路径
  314. * @return string
  315. */
  316. public function getBasename(string $file_path)
  317. {
  318. $file_path = $this->dirReplace($file_path);
  319. return basename(str_replace('\\', '/', $file_path));
  320. //return pathinfo($file_path,PATHINFO_BASENAME);
  321. }
  322. /**
  323. * 获取文件后缀名
  324. * @param string $file_name 文件路径
  325. * @return string
  326. */
  327. public static function getExt(string $file)
  328. {
  329. $file = self::dirReplace($file);
  330. return pathinfo($file, PATHINFO_EXTENSION);
  331. }
  332. /**
  333. * 取得指定目录名称
  334. * @param string $path 文件路径
  335. * @param int $num 需要返回以上级目录的数
  336. * @return string
  337. */
  338. public function fatherDir(string $path, $num = 1)
  339. {
  340. $path = $this->dirReplace($path);
  341. $arr = explode('/', $path);
  342. if ($num == 0 || count($arr) < $num) return pathinfo($path, PATHINFO_BASENAME);
  343. return substr(strrev($path), 0, 1) == '/' ? $arr[(count($arr) - (1 + $num))] : $arr[(count($arr) - $num)];
  344. }
  345. /**
  346. * 删除文件
  347. * @param string $path
  348. * @return boolean
  349. */
  350. public function unlinkFile(string $path)
  351. {
  352. $path = $this->dirReplace($path);
  353. if (file_exists($path)) {
  354. return unlink($path);
  355. }
  356. }
  357. /**
  358. * 文件操作(复制/移动)
  359. * @param string $old_path 指定要操作文件路径(需要含有文件名和后缀名)
  360. * @param string $new_path 指定新文件路径(需要新的文件名和后缀名)
  361. * @param string $type 文件操作类型
  362. * @param boolean $overWrite 是否覆盖已存在文件
  363. * @return boolean
  364. */
  365. public function handleFile(string $old_path, string $new_path, string $type = 'copy', bool $overWrite = FALSE)
  366. {
  367. $old_path = $this->dirReplace($old_path);
  368. $new_path = $this->dirReplace($new_path);
  369. if (file_exists($new_path) && $overWrite = FALSE) {
  370. return FALSE;
  371. } else if (file_exists($new_path) && $overWrite = TRUE) {
  372. $this->unlinkFile($new_path);
  373. }
  374. $aimDir = dirname($new_path);
  375. $this->createDir($aimDir);
  376. switch ($type) {
  377. case 'copy':
  378. return copy($old_path, $new_path);
  379. break;
  380. case 'move':
  381. return @rename($old_path, $new_path);
  382. break;
  383. }
  384. }
  385. /**
  386. * 文件夹操作(复制/移动)
  387. * @param string $old_path 指定要操作文件夹路径
  388. * @param string $aimDir 指定新文件夹路径
  389. * @param string $type 操作类型
  390. * @param boolean $overWrite 是否覆盖文件和文件夹
  391. * @return boolean
  392. */
  393. public function handleDir(string $old_path, string $new_path, string $type = 'copy', bool $overWrite = FALSE)
  394. {
  395. $new_path = $this->checkPath($new_path);
  396. $old_path = $this->checkPath($old_path);
  397. if (!is_dir($old_path)) return FALSE;
  398. if (!file_exists($new_path)) $this->createDir($new_path);
  399. $dirHandle = opendir($old_path);
  400. if (!$dirHandle) return FALSE;
  401. $boolean = TRUE;
  402. while (FALSE !== ($file = readdir($dirHandle))) {
  403. if ($file == '.' || $file == '..') continue;
  404. if (!is_dir($old_path . $file)) {
  405. $boolean = $this->handleFile($old_path . $file, $new_path . $file, $type, $overWrite);
  406. } else {
  407. $this->handleDir($old_path . $file, $new_path . $file, $type, $overWrite);
  408. }
  409. }
  410. switch ($type) {
  411. case 'copy':
  412. closedir($dirHandle);
  413. return $boolean;
  414. break;
  415. case 'move':
  416. closedir($dirHandle);
  417. return @rmdir($old_path);
  418. break;
  419. }
  420. }
  421. /**
  422. * 替换相应的字符
  423. * @param string $path 路径
  424. * @return string
  425. */
  426. public static function dirReplace(string $path)
  427. {
  428. return str_replace('//', '/', str_replace('\\', '/', $path));
  429. }
  430. /**
  431. * 读取指定路径下模板文件
  432. * @param string $path 指定路径下的文件
  433. * @return string $rstr
  434. */
  435. public static function getTempltes(string $path)
  436. {
  437. $path = self::dirReplace($path);
  438. if (file_exists($path)) {
  439. $fp = fopen($path, 'r');
  440. $rstr = fread($fp, filesize($path));
  441. fclose($fp);
  442. return $rstr;
  443. } else {
  444. return '';
  445. }
  446. }
  447. /**
  448. * @param string $oldname 原始名称
  449. * @param string $newname 新名称
  450. * @return bool
  451. */
  452. public function rename(string $oldname, string $newname)
  453. {
  454. if (($newname != $oldname) && is_writable($oldname)) {
  455. return rename($oldname, $newname);
  456. }
  457. }
  458. /**
  459. * 获取指定路径下的信息
  460. * @param string $dir 路径
  461. * @return ArrayObject
  462. */
  463. public function getDirInfo(string $dir)
  464. {
  465. $handle = @opendir($dir);//打开指定目录
  466. $directory_count = 0;
  467. while (FALSE !== ($file_path = readdir($handle))) {
  468. if ($file_path != "." && $file_path != "..") {
  469. //is_dir("$dir/$file_path") ? $sizeResult += $this->get_dir_size("$dir/$file_path") : $sizeResult += filesize("$dir/$file_path");
  470. $next_path = $dir . '/' . $file_path;
  471. if (is_dir($next_path)) {
  472. $directory_count++;
  473. $result_value = self::getDirInfo($next_path);
  474. $total_size += $result_value['size'];
  475. $file_cout += $result_value['filecount'];
  476. $directory_count += $result_value['dircount'];
  477. } elseif (is_file($next_path)) {
  478. $total_size += filesize($next_path);
  479. $file_cout++;
  480. }
  481. }
  482. }
  483. closedir($handle);//关闭指定目录
  484. $result_value['size'] = $total_size;
  485. $result_value['filecount'] = $file_cout;
  486. $result_value['dircount'] = $directory_count;
  487. return $result_value;
  488. }
  489. /**
  490. * 指定文件编码转换
  491. * @param string $path 文件路径
  492. * @param string $input_code 原始编码
  493. * @param string $out_code 输出编码
  494. * @return boolean
  495. */
  496. public function changeFileCode(string $path, string $input_code, string $out_code)
  497. {
  498. if (is_file($path))//检查文件是否存在,如果存在就执行转码,返回真
  499. {
  500. $content = file_get_contents($path);
  501. $content = string::chang_code($content, $input_code, $out_code);
  502. $fp = fopen($path, 'w');
  503. return fputs($fp, $content) ? TRUE : FALSE;
  504. fclose($fp);
  505. }
  506. }
  507. /**
  508. * 指定目录下指定条件文件编码转换
  509. * @param string $dirname 目录路径
  510. * @param string $input_code 原始编码
  511. * @param string $out_code 输出编码
  512. * @param boolean $is_all 是否转换所有子目录下文件编码
  513. * @param string $exts 文件类型
  514. * @return boolean
  515. */
  516. public function changeDirFilesCode(string $dirname, string $input_code, string $out_code, bool $is_all = TRUE, string $exts = '')
  517. {
  518. if (is_dir($dirname)) {
  519. $fh = opendir($dirname);
  520. while (($file = readdir($fh)) !== FALSE) {
  521. if (strcmp($file, '.') == 0 || strcmp($file, '..') == 0) {
  522. continue;
  523. }
  524. $filepath = $dirname . '/' . $file;
  525. if (is_dir($filepath) && $is_all == TRUE) {
  526. $files = $this->changeDirFilesCode($filepath, $input_code, $out_code, $is_all, $exts);
  527. } else {
  528. if ($this->getExt($filepath) == $exts && is_file($filepath)) {
  529. $boole = $this->changeFileCode($filepath, $input_code, $out_code, $is_all, $exts);
  530. if (!$boole) continue;
  531. }
  532. }
  533. }
  534. closedir($fh);
  535. return TRUE;
  536. } else {
  537. return FALSE;
  538. }
  539. }
  540. /**
  541. * 列出指定目录下符合条件的文件和文件夹
  542. * @param string $dirname 路径
  543. * @param boolean $is_all 是否列出子目录中的文件
  544. * @param string $exts 需要列出的后缀名文件
  545. * @param string $sort 数组排序
  546. * @return ArrayObject
  547. */
  548. public function listDirInfo(string $dirname, bool $is_all = FALSE, string $exts = '', string $sort = 'ASC')
  549. {
  550. //处理多于的/号
  551. $new = strrev($dirname);
  552. if (strpos($new, '/') == 0) {
  553. $new = substr($new, 1);
  554. }
  555. $dirname = strrev($new);
  556. $sort = strtolower($sort);//将字符转换成小写
  557. $files = [];
  558. $subfiles = [];
  559. if (is_dir($dirname)) {
  560. $fh = opendir($dirname);
  561. while (($file = readdir($fh)) !== FALSE) {
  562. if (strcmp($file, '.') == 0 || strcmp($file, '..') == 0) continue;
  563. $filepath = $dirname . '/' . $file;
  564. switch ($exts) {
  565. case '*':
  566. if (is_dir($filepath) && $is_all == TRUE) {
  567. $files = array_merge($files, self::listDirInfo($filepath, $is_all, $exts, $sort));
  568. }
  569. array_push($files, $filepath);
  570. break;
  571. case 'folder':
  572. if (is_dir($filepath) && $is_all == TRUE) {
  573. $files = array_merge($files, self::listDirInfo($filepath, $is_all, $exts, $sort));
  574. array_push($files, $filepath);
  575. } elseif (is_dir($filepath)) {
  576. array_push($files, $filepath);
  577. }
  578. break;
  579. case 'file':
  580. if (is_dir($filepath) && $is_all == TRUE) {
  581. $files = array_merge($files, self::listDirInfo($filepath, $is_all, $exts, $sort));
  582. } elseif (is_file($filepath)) {
  583. array_push($files, $filepath);
  584. }
  585. break;
  586. default:
  587. if (is_dir($filepath) && $is_all == TRUE) {
  588. $files = array_merge($files, self::listDirInfo($filepath, $is_all, $exts, $sort));
  589. } elseif (preg_match("/\.($exts)/i", $filepath) && is_file($filepath)) {
  590. array_push($files, $filepath);
  591. }
  592. break;
  593. }
  594. switch ($sort) {
  595. case 'asc':
  596. sort($files);
  597. break;
  598. case 'desc':
  599. rsort($files);
  600. break;
  601. case 'nat':
  602. natcasesort($files);
  603. break;
  604. }
  605. }
  606. closedir($fh);
  607. return $files;
  608. } else {
  609. return FALSE;
  610. }
  611. }
  612. /**
  613. * 返回指定路径的文件夹信息,其中包含指定路径中的文件和目录
  614. * @param string $dir
  615. * @return ArrayObject
  616. */
  617. public function dirInfo(string $dir)
  618. {
  619. return scandir($dir);
  620. }
  621. /**
  622. * 判断目录是否为空
  623. * @param string $dir
  624. * @return boolean
  625. */
  626. public function isEmpty(string $dir)
  627. {
  628. $handle = opendir($dir);
  629. while (($file = readdir($handle)) !== false) {
  630. if ($file != '.' && $file != '..') {
  631. closedir($handle);
  632. return true;
  633. }
  634. }
  635. closedir($handle);
  636. return false;
  637. }
  638. /**
  639. * 返回指定文件和目录的信息
  640. * @param string $file
  641. * @return ArrayObject
  642. */
  643. public static function listInfo(string $file)
  644. {
  645. $dir = [];
  646. $dir['filename'] = basename($file);//返回路径中的文件名部分。
  647. $dir['pathname'] = strstr(php_uname('s'), 'Windows') ? str_replace('\\', '\\\\', realpath($file)) : realpath($file);//返回绝对路径名。
  648. $dir['owner'] = fileowner($file);//文件的 user ID (所有者)。
  649. $dir['perms'] = fileperms($file);//返回文件的 inode 编号。
  650. $dir['inode'] = fileinode($file);//返回文件的 inode 编号。
  651. $dir['group'] = filegroup($file);//返回文件的组 ID。
  652. $dir['path'] = dirname($file);//返回路径中的目录名称部分。
  653. $dir['atime'] = fileatime($file);//返回文件的上次访问时间。
  654. $dir['ctime'] = filectime($file);//返回文件的上次改变时间。
  655. $dir['perms'] = fileperms($file);//返回文件的权限。
  656. $dir['size'] = self::byteFormat(filesize($file), 2);//返回文件大小。
  657. $dir['type'] = filetype($file);//返回文件类型。
  658. $dir['ext'] = is_file($file) ? pathinfo($file, PATHINFO_EXTENSION) : '';//返回文件后缀名
  659. $dir['mtime'] = filemtime($file);//返回文件的上次修改时间。
  660. $dir['isDir'] = is_dir($file);//判断指定的文件名是否是一个目录。
  661. $dir['isFile'] = is_file($file);//判断指定文件是否为常规的文件。
  662. $dir['isLink'] = is_link($file);//判断指定的文件是否是连接。
  663. $dir['isReadable'] = is_readable($file);//判断文件是否可读。
  664. $dir['isWritable'] = is_writable($file);//判断文件是否可写。
  665. $dir['isUpload'] = is_uploaded_file($file);//判断文件是否是通过 HTTP POST 上传的。
  666. return $dir;
  667. }
  668. /**
  669. * 返回关于打开文件的信息
  670. * @param $file
  671. * @return ArrayObject
  672. * 数字下标 关联键名(自 PHP 4.0.6) 说明
  673. * 0 dev 设备名
  674. * 1 ino 号码
  675. * 2 mode inode 保护模式
  676. * 3 nlink 被连接数目
  677. * 4 uid 所有者的用户 id
  678. * 5 gid 所有者的组 id
  679. * 6 rdev 设备类型,如果是 inode 设备的话
  680. * 7 size 文件大小的字节数
  681. * 8 atime 上次访问时间(Unix 时间戳)
  682. * 9 mtime 上次修改时间(Unix 时间戳)
  683. * 10 ctime 上次改变时间(Unix 时间戳)
  684. * 11 blksize 文件系统 IO 的块大小
  685. * 12 blocks 所占据块的数目
  686. */
  687. public function openInfo(string $file)
  688. {
  689. $file = fopen($file, "r");
  690. $result = fstat($file);
  691. fclose($file);
  692. return $result;
  693. }
  694. /**
  695. * 改变文件和目录的相关属性
  696. * @param string $file 文件路径
  697. * @param string $type 操作类型
  698. * @param string $ch_info 操作信息
  699. * @return boolean
  700. */
  701. public function change_file($file, $type, $ch_info)
  702. {
  703. switch ($type) {
  704. case 'group' :
  705. $is_ok = chgrp($file, $ch_info);//改变文件组。
  706. break;
  707. case 'mode' :
  708. $is_ok = chmod($file, $ch_info);//改变文件模式。
  709. break;
  710. case 'ower' :
  711. $is_ok = chown($file, $ch_info);//改变文件所有者。
  712. break;
  713. }
  714. }
  715. /**
  716. * 取得文件路径信息
  717. * @param $full_path 完整路径
  718. * @return ArrayObject
  719. */
  720. public function getFileType(string $path)
  721. {
  722. //pathinfo() 函数以数组的形式返回文件路径的信息。
  723. //---------$file_info = pathinfo($path); echo file_info['extension'];----------//
  724. //extension取得文件后缀名【pathinfo($path,PATHINFO_EXTENSION)】-----dirname取得文件路径【pathinfo($path,PATHINFO_DIRNAME)】-----basename取得文件完整文件名【pathinfo($path,PATHINFO_BASENAME)】-----filename取得文件名【pathinfo($path,PATHINFO_FILENAME)】
  725. return pathinfo($path);
  726. }
  727. /**
  728. * 取得上传文件信息
  729. * @param $file file属性信息
  730. * @return array
  731. */
  732. public function getUploadFileInfo($file)
  733. {
  734. $file_info = request()->file($file);//取得上传文件基本信息
  735. $info = [];
  736. $info['type'] = strtolower(trim(stripslashes(preg_replace("/^(.+?);.*$/", "\\1", $file_info['type'])), '"'));//取得文件类型
  737. $info['temp'] = $file_info['tmp_name'];//取得上传文件在服务器中临时保存目录
  738. $info['size'] = $file_info['size'];//取得上传文件大小
  739. $info['error'] = $file_info['error'];//取得文件上传错误
  740. $info['name'] = $file_info['name'];//取得上传文件名
  741. $info['ext'] = $this->getExt($file_info['name']);//取得上传文件后缀
  742. return $info;
  743. }
  744. /**
  745. * 设置文件命名规则
  746. * @param string $type 命名规则
  747. * @param string $filename 文件名
  748. * @return string
  749. */
  750. public function setFileName(string $type)
  751. {
  752. switch ($type) {
  753. case 'hash' :
  754. $new_file = md5(uniqid(mt_rand()));//mt_srand()以随机数md5加密来命名
  755. break;
  756. case 'time' :
  757. $new_file = time();
  758. break;
  759. default :
  760. $new_file = date($type, time());//以时间格式来命名
  761. break;
  762. }
  763. return $new_file;
  764. }
  765. /**
  766. * 文件保存路径处理
  767. * @return string
  768. */
  769. public function checkPath($path)
  770. {
  771. return (preg_match('/\/$/', $path)) ? $path : $path . '/';
  772. }
  773. /**
  774. * 文件下载
  775. * $save_dir 保存路径
  776. * $filename 文件名
  777. * @return array
  778. */
  779. public static function downRemoteFile(string $url, string $save_dir = '', string $filename = '', int $type = 0)
  780. {
  781. if (trim($url) == '') {
  782. return ['file_name' => '', 'save_path' => '', 'error' => 1];
  783. }
  784. if (trim($save_dir) == '') {
  785. $save_dir = './';
  786. }
  787. if (trim($filename) == '') {//保存文件名
  788. $ext = strrchr($url, '.');
  789. // if($ext!='.gif'&&$ext!='.jpg'){
  790. // return ['file_name'=>'','save_path'=>'','error'=>3];
  791. // }
  792. $filename = time() . $ext;
  793. }
  794. if (0 !== strrpos($save_dir, '/')) {
  795. $save_dir .= '/';
  796. }
  797. //创建保存目录
  798. if (!file_exists($save_dir) && !mkdir($save_dir, 0777, true)) {
  799. return ['file_name' => '', 'save_path' => '', 'error' => 5];
  800. }
  801. //获取远程文件所采用的方法
  802. if ($type) {
  803. $ch = curl_init();
  804. $timeout = 5;
  805. curl_setopt($ch, CURLOPT_URL, $url);
  806. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  807. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
  808. $img = curl_exec($ch);
  809. curl_close($ch);
  810. } else {
  811. ob_start();
  812. readfile($url);
  813. $img = ob_get_contents();
  814. ob_end_clean();
  815. }
  816. //$size=strlen($img);
  817. //文件大小
  818. $fp2 = fopen($save_dir . $filename, 'a');
  819. fwrite($fp2, $img);
  820. fclose($fp2);
  821. unset($img, $url);
  822. return ['file_name' => $filename, 'save_path' => $save_dir . $filename, 'error' => 0];
  823. }
  824. /**
  825. * 解压zip文件
  826. * @param string $filename
  827. * @param string $savename
  828. * @return bool
  829. */
  830. public static function zipOpen(string $filename, string $savename)
  831. {
  832. $zip = new \ZipArchive;
  833. $zipfile = $filename;
  834. $res = $zip->open($zipfile);
  835. $toDir = $savename;
  836. if (!file_exists($toDir)) mkdir($toDir, 0777);
  837. $docnum = $zip->numFiles;
  838. for ($i = 0; $i < $docnum; $i++) {
  839. $statInfo = $zip->statIndex($i);
  840. if ($statInfo['crc'] == 0 && $statInfo['comp_size'] != 2) {
  841. //新建目录
  842. mkdir($toDir . '/' . substr($statInfo['name'], 0, -1), 0777);
  843. } else {
  844. //拷贝文件
  845. copy('zip://' . $zipfile . '#' . $statInfo['name'], $toDir . '/' . $statInfo['name']);
  846. }
  847. }
  848. $zip->close();
  849. return true;
  850. }
  851. /**
  852. *设置字体格式
  853. * @param $title string 必选
  854. * return string
  855. */
  856. public static function setUtf8($title)
  857. {
  858. return iconv('utf-8', 'gb2312', $title);
  859. }
  860. /**
  861. *检查指定文件是否能写入
  862. * @param $file string 必选
  863. * return boole
  864. */
  865. public static function isWritable($file)
  866. {
  867. $file = str_replace('\\', '/', $file);
  868. if (!file_exists($file)) return false;
  869. return is_writable($file);
  870. }
  871. }