FilesUtil.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <?php
  2. namespace PhpZip\Util;
  3. use PhpZip\Util\Iterator\IgnoreFilesFilterIterator;
  4. use PhpZip\Util\Iterator\IgnoreFilesRecursiveFilterIterator;
  5. /**
  6. * Files util.
  7. *
  8. * @author Ne-Lexa alexey@nelexa.ru
  9. * @license MIT
  10. */
  11. class FilesUtil
  12. {
  13. /**
  14. * Is empty directory
  15. *
  16. * @param string $dir Directory
  17. * @return bool
  18. */
  19. public static function isEmptyDir($dir)
  20. {
  21. if (!is_readable($dir)) {
  22. return false;
  23. }
  24. return count(scandir($dir)) === 2;
  25. }
  26. /**
  27. * Remove recursive directory.
  28. *
  29. * @param string $dir Directory path.
  30. */
  31. public static function removeDir($dir)
  32. {
  33. $files = new \RecursiveIteratorIterator(
  34. new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS),
  35. \RecursiveIteratorIterator::CHILD_FIRST
  36. );
  37. foreach ($files as $fileInfo) {
  38. $function = ($fileInfo->isDir() ? 'rmdir' : 'unlink');
  39. $function($fileInfo->getRealPath());
  40. }
  41. rmdir($dir);
  42. }
  43. /**
  44. * Convert glob pattern to regex pattern.
  45. *
  46. * @param string $globPattern
  47. * @return string
  48. */
  49. public static function convertGlobToRegEx($globPattern)
  50. {
  51. // Remove beginning and ending * globs because they're useless
  52. $globPattern = trim($globPattern, '*');
  53. $escaping = false;
  54. $inCurrent = 0;
  55. $chars = str_split($globPattern);
  56. $regexPattern = '';
  57. foreach ($chars AS $currentChar) {
  58. switch ($currentChar) {
  59. case '*':
  60. $regexPattern .= ($escaping ? "\\*" : '.*');
  61. $escaping = false;
  62. break;
  63. case '?':
  64. $regexPattern .= ($escaping ? "\\?" : '.');
  65. $escaping = false;
  66. break;
  67. case '.':
  68. case '(':
  69. case ')':
  70. case '+':
  71. case '|':
  72. case '^':
  73. case '$':
  74. case '@':
  75. case '%':
  76. $regexPattern .= '\\' . $currentChar;
  77. $escaping = false;
  78. break;
  79. case '\\':
  80. if ($escaping) {
  81. $regexPattern .= "\\\\";
  82. $escaping = false;
  83. } else {
  84. $escaping = true;
  85. }
  86. break;
  87. case '{':
  88. if ($escaping) {
  89. $regexPattern .= "\\{";
  90. } else {
  91. $regexPattern = '(';
  92. $inCurrent++;
  93. }
  94. $escaping = false;
  95. break;
  96. case '}':
  97. if ($inCurrent > 0 && !$escaping) {
  98. $regexPattern .= ')';
  99. $inCurrent--;
  100. } else if ($escaping)
  101. $regexPattern = "\\}";
  102. else
  103. $regexPattern = "}";
  104. $escaping = false;
  105. break;
  106. case ',':
  107. if ($inCurrent > 0 && !$escaping) {
  108. $regexPattern .= '|';
  109. } else if ($escaping)
  110. $regexPattern .= "\\,";
  111. else
  112. $regexPattern = ",";
  113. break;
  114. default:
  115. $escaping = false;
  116. $regexPattern .= $currentChar;
  117. }
  118. }
  119. return $regexPattern;
  120. }
  121. /**
  122. * Search files.
  123. *
  124. * @param string $inputDir
  125. * @param bool $recursive
  126. * @param array $ignoreFiles
  127. * @return array Searched file list
  128. */
  129. public static function fileSearchWithIgnore($inputDir, $recursive = true, array $ignoreFiles = [])
  130. {
  131. $directoryIterator = $recursive ?
  132. new \RecursiveDirectoryIterator($inputDir) :
  133. new \DirectoryIterator($inputDir);
  134. if (!empty($ignoreFiles)) {
  135. $directoryIterator = $recursive ?
  136. new IgnoreFilesRecursiveFilterIterator($directoryIterator, $ignoreFiles) :
  137. new IgnoreFilesFilterIterator($directoryIterator, $ignoreFiles);
  138. }
  139. $iterator = $recursive ?
  140. new \RecursiveIteratorIterator($directoryIterator) :
  141. new \IteratorIterator($directoryIterator);
  142. $fileList = [];
  143. foreach ($iterator as $file) {
  144. if ($file instanceof \SplFileInfo) {
  145. $fileList[] = $file->getPathname();
  146. }
  147. }
  148. return $fileList;
  149. }
  150. /**
  151. * Search files from glob pattern.
  152. *
  153. * @param string $globPattern
  154. * @param int $flags
  155. * @param bool $recursive
  156. * @return array Searched file list
  157. */
  158. public static function globFileSearch($globPattern, $flags = 0, $recursive = true)
  159. {
  160. $flags = (int)$flags;
  161. $recursive = (bool)$recursive;
  162. $files = glob($globPattern, $flags);
  163. if (!$recursive) {
  164. return $files;
  165. }
  166. foreach (glob(dirname($globPattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
  167. $files = array_merge($files, self::globFileSearch($dir . '/' . basename($globPattern), $flags, $recursive));
  168. }
  169. return $files;
  170. }
  171. /**
  172. * Search files from regex pattern.
  173. *
  174. * @param string $folder
  175. * @param string $pattern
  176. * @param bool $recursive
  177. * @return array Searched file list
  178. */
  179. public static function regexFileSearch($folder, $pattern, $recursive = true)
  180. {
  181. $directoryIterator = $recursive ? new \RecursiveDirectoryIterator($folder) : new \DirectoryIterator($folder);
  182. $iterator = $recursive ? new \RecursiveIteratorIterator($directoryIterator) : new \IteratorIterator($directoryIterator);
  183. $regexIterator = new \RegexIterator($iterator, $pattern, \RegexIterator::MATCH);
  184. $fileList = [];
  185. foreach ($regexIterator as $file) {
  186. if ($file instanceof \SplFileInfo) {
  187. $fileList[] = $file->getPathname();
  188. }
  189. }
  190. return $fileList;
  191. }
  192. /**
  193. * Convert bytes to human size.
  194. *
  195. * @param int $size Size bytes
  196. * @param string|null $unit Unit support 'GB', 'MB', 'KB'
  197. * @return string
  198. */
  199. public static function humanSize($size, $unit = null)
  200. {
  201. if (($unit === null && $size >= 1 << 30) || $unit === "GB")
  202. return number_format($size / (1 << 30), 2) . "GB";
  203. if (($unit === null && $size >= 1 << 20) || $unit === "MB")
  204. return number_format($size / (1 << 20), 2) . "MB";
  205. if (($unit === null && $size >= 1 << 10) || $unit === "KB")
  206. return number_format($size / (1 << 10), 2) . "KB";
  207. return number_format($size) . " bytes";
  208. }
  209. }