1: <?php
2:
3: namespace ngatngay;
4:
5: use SplFileInfo;
6: use Exception;
7: use FilesystemIterator;
8: use RecursiveCallbackFilterIterator;
9: use RecursiveDirectoryIterator;
10: use RecursiveIteratorIterator;
11:
12: // file system
13: class fs
14: {
15: /*
16: * file, file1, file2...
17: */
18: function name_increment(string $file_name_body, string $file_ext): string
19: {
20: $i = 1;
21: $file_exists = true;
22:
23: do {
24: $file_save = $file_name_body . $i . '.' . $file_ext;
25:
26: if (!file_exists($file_save)) {
27: $file_exists = false;
28: }
29:
30: $i++;
31: } while ($file_exists);
32:
33: return $file_save;
34: }
35:
36: public static function get_extension(string $name): string
37: {
38: return (new SplFileInfo($name))->getExtension();
39: }
40:
41: public static function size(string $path): int {
42: if (!is_dir($path)) {
43: return filesize($path);
44: }
45:
46: $size = 0;
47:
48: $iterator = new RecursiveIteratorIterator(
49: new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS | FilesystemIterator::FOLLOW_SYMLINKS),
50: RecursiveIteratorIterator::LEAVES_ONLY
51: );
52:
53: foreach ($iterator as $file) {
54: if ($file->isFile()) {
55: $size += $file->getSize();
56: }
57: }
58:
59: return $size;
60: }
61:
62: /**
63: * @param $fileSize string
64: * @return string
65: */
66: public static function readable_size(int $fileSize): string
67: {
68: $size = floatval($fileSize);
69:
70: if ($size < 1024) {
71: $s = $size . ' B';
72: } elseif ($size < 1048576) {
73: $s = round($size / 1024, 2) . ' KB';
74: } elseif ($size < 1073741824) {
75: $s = round($size / 1048576, 2) . ' MB';
76: } elseif ($size < 1099511627776) {
77: $s = round($size / 1073741824, 2) . ' GB';
78: } elseif ($size < 1125899906842624) {
79: $s = round($size / 1099511627776, 2) . ' TB';
80: } elseif ($size < 1152921504606846976) {
81: $s = round($size / 1125899906842624, 2) . ' PB';
82: } elseif ($size < 1.1805916207174E+21) {
83: $s = round($size / 1152921504606846976, 2) . ' EB';
84: } elseif ($size < 1.2089258196146E+24) {
85: $s = round($size / 1.1805916207174E+21, 2) . ' ZB';
86: } else {
87: $s = round($size / 1.2089258196146E+24, 2) . ' YB';
88: }
89:
90: return $s;
91: }
92:
93: public static function remove(string $path): bool
94: {
95: if (is_link($path)) {
96: return unlink($path);
97: }
98:
99: if (is_file($path)) {
100: return unlink($path);
101: }
102:
103: if (is_dir($path)) {
104: $files = array_diff(scandir($path), ['.', '..']);
105: foreach ($files as $file) {
106: $filePath = $path . DIRECTORY_SEPARATOR . $file;
107: if (!self::remove($filePath)) {
108: return false;
109: }
110: }
111: return rmdir($path);
112: }
113:
114: if (!file_exists($path)) {
115: return true;
116: }
117:
118: throw new Exception('remove error, not match file type');
119: }
120:
121: public static function read_full_dir(string $path, array $excludes = []): mixed
122: {
123: $directory = new RecursiveDirectoryIterator(
124: $path,
125: FilesystemIterator::UNIX_PATHS
126: | FilesystemIterator::SKIP_DOTS
127: );
128:
129: $filter = new RecursiveCallbackFilterIterator($directory, function ($current, $key, $iterator) use ($path, $excludes) {
130: $relativePath = str::replace_first($path, '', $current->getPathname());
131:
132: foreach ($excludes as $exclude) {
133: if (empty($exclude)) {
134: continue;
135: }
136: //var_dump($relativePath);
137: //var_dump($exclude);
138:
139: $exclude = trim($exclude);
140: $exclude = trim($exclude, '/');
141: $relativePath = trim($relativePath, '/');
142:
143: if (str_ends_with($relativePath, $exclude)) {
144: return false;
145: }
146: }
147:
148: return true;
149: });
150:
151: return new RecursiveIteratorIterator(
152: $filter,
153: RecursiveIteratorIterator::SELF_FIRST
154: );
155: }
156:
157: public static function join_path(string ...$paths): string {
158: return preg_replace('#/+#', '/', implode('/', $paths));
159: }
160: }
161: