99
1010namespace Toolkit \FsUtil ;
1111
12- use Closure ;
1312use InvalidArgumentException ;
14- use SplFileInfo ;
1513use Toolkit \FsUtil \Exception \FileNotFoundException ;
1614use Toolkit \FsUtil \Traits \DirOperateTrait ;
15+ use function array_merge ;
1716use function basename ;
1817use function glob ;
1918use function implode ;
2322use function preg_match ;
2423use function strlen ;
2524use function trim ;
25+ use const GLOB_BRACE ;
2626
2727/**
2828 * Class Directory
@@ -37,9 +37,9 @@ class Directory extends FileSystem
3737 * 只获得目录结构
3838 *
3939 * @param string $path
40- * @param int $pid
41- * @param bool $son
42- * @param array $list
40+ * @param int $pid
41+ * @param bool $son
42+ * @param array $list
4343 *
4444 * @return array
4545 * @throws FileNotFoundException
@@ -74,9 +74,9 @@ public static function getList(string $path, int $pid = 0, bool $son = false, ar
7474
7575 /**
7676 * @param string $path
77- * @param bool $loop
78- * @param null $parent
79- * @param array $list
77+ * @param bool $loop
78+ * @param null $parent
79+ * @param array $list
8080 *
8181 * @return array
8282 */
@@ -107,9 +107,9 @@ public static function getDirs(string $path, bool $loop = false, $parent = null,
107107 /**
108108 * 获得目录下的文件,可选择类型、是否遍历子文件夹
109109 *
110- * @param string $dir string 目标目录
111- * @param array|string $ext array('css','html','php') css|html|php
112- * @param bool $recursive int|bool 是否包含子目录
110+ * @param string $dir string 目标目录
111+ * @param array|string $ext array('css','html','php') css|html|php
112+ * @param bool $recursive int|bool 是否包含子目录
113113 *
114114 * @return array
115115 * @throws FileNotFoundException
@@ -148,11 +148,11 @@ public static function simpleInfo(string $dir, array|string $ext = '', bool $rec
148148 /**
149149 * 获得目录下的文件,可选择类型、是否遍历子文件夹
150150 *
151- * @param string $path string 目标目录
152- * @param array|string $ext array('css','html','php') css|html|php
153- * @param bool $recursive 是否包含子目录
154- * @param string $parent
155- * @param array $list
151+ * @param string $path string 目标目录
152+ * @param array|string $ext array('css','html','php') css|html|php
153+ * @param bool $recursive 是否包含子目录
154+ * @param string $parent
155+ * @param array $list
156156 *
157157 * @return array
158158 * @throws FileNotFoundException
@@ -190,10 +190,10 @@ public static function getFiles(
190190 /**
191191 * 获得目录下的文件以及详细信息,可选择类型、是否遍历子文件夹
192192 *
193- * @param string $path string 目标目录
194- * @param array|string $ext array('css','html','php') css|html|php
195- * @param bool $recursive 是否包含子目录
196- * @param array $list
193+ * @param string $path string 目标目录
194+ * @param array|string $ext array('css','html','php') css|html|php
195+ * @param bool $recursive 是否包含子目录
196+ * @param array $list
197197 *
198198 * @return array
199199 * @throws InvalidArgumentException
@@ -230,8 +230,8 @@ public static function getFilesInfo(string $path, array|string $ext = '', bool $
230230 * 支持层级目录的创建
231231 *
232232 * @param string $path
233- * @param int $mode
234- * @param bool $recursive
233+ * @param int $mode
234+ * @param bool $recursive
235235 *
236236 * @return bool
237237 */
@@ -267,42 +267,78 @@ public static function mkSubDirs(string $parentDir, array $subDirs, int $mode =
267267 *
268268 * @param string $oldDir
269269 * @param string $newDir
270+ * @param array $options = [
271+ * 'skipExist' => true,
272+ * 'beforeFn' => function (): bool { },
273+ * 'afterFn' => function (): void { },
274+ * ]
270275 *
271276 * @return bool
272277 */
273- public static function copy (string $ oldDir , string $ newDir ): bool
278+ public static function copy (string $ oldDir , string $ newDir, array $ options = [] ): bool
274279 {
275- $ oldDir = self ::pathFormat ($ oldDir );
276- $ newDir = self ::pathFormat ($ newDir );
277-
278280 if (!is_dir ($ oldDir )) {
279281 throw new FileNotFoundException ('copy failed: ' . $ oldDir . ' does not exist! ' );
280282 }
281283
284+ self ::doCopy ($ oldDir , $ newDir , array_merge ([
285+ 'skipExist ' => true ,
286+ 'beforeFn ' => null ,
287+ 'afterFn ' => null ,
288+ ], $ options ));
289+
290+ return true ;
291+ }
292+
293+ /**
294+ * @param string $oldDir
295+ * @param string $newDir
296+ * @param array $options
297+ *
298+ * @return void
299+ */
300+ private static function doCopy (string $ oldDir , string $ newDir , array $ options ): void
301+ {
282302 self ::create ($ newDir );
283- foreach (glob ($ oldDir . '* ' ) as $ v ) {
284- $ newFile = $ newDir . basename ($ v );//文件
303+ $ beforeFn = $ options ['beforeFn ' ];
285304
286- //文件存在,跳过复制它
287- if (file_exists ($ newFile )) {
305+ // use '{,.}*' match hidden files
306+ foreach (glob ($ oldDir . '/{,.}* ' , GLOB_BRACE ) as $ old ) {
307+ $ name = basename ($ old );
308+ if ($ name === '. ' || $ name === '.. ' ) {
288309 continue ;
289310 }
290311
291- if ( is_dir ( $ v )) {
292- self :: copy ( $ v , $ newFile );
293- } else {
294- copy ( $ v , $ newFile ); //是文件就复制过来
295- @ chmod ( $ newFile , 0664 ); // 权限 0777
312+ $ new = self :: joinPath ( $ newDir , $ name );
313+
314+ if ( is_dir ( $ old )) {
315+ self :: doCopy ( $ old , $ new , $ options );
316+ continue ;
296317 }
297- }
298318
299- return true ;
319+ // return false to skip copy
320+ if ($ beforeFn && !$ beforeFn ($ old )) {
321+ continue ;
322+ }
323+
324+ if ($ options ['skipExist ' ] && file_exists ($ new )) {
325+ continue ;
326+ }
327+
328+ // do copy
329+ copy ($ old , $ new );
330+ @chmod ($ new , 0664 ); // 权限 0777
331+
332+ if ($ afterFn = $ options ['afterFn ' ]) {
333+ $ afterFn ($ new );
334+ }
335+ }
300336 }
301337
302338 /**
303339 * 删除目录及里面的文件
304340 *
305- * @param string $path
341+ * @param string $path
306342 * @param boolean $delSelf 默认最后删掉自己
307343 *
308344 * @return bool
0 commit comments