PHP遍历目录下所有文件以及文件夹复制功能

PHP遍历目录下所有文件以及文件夹复制功能


class Dir
{
    /**
     * 扫描目录下所有文件,
     * @var array
     */
    protected static $files = [];

    public static $ret = [];

    /**
     * 扫描目录路径
     * @param $path string 带扫描的路径
     * @param array $options 要附加的选项,后面可以根据自己需求扩展
     * @return array
     * @author: Vencenty
     * @time: 2019/6/28 10:57
     */
    static function scan($path, $options = [])
    {
        $options = array_merge([
            'callback'  => null, // 对查找到的文件进行操作
            'filterExt' => [], // 要过滤的文件后缀
        ], $options);

        $scanQueue = [$path];

        while (count($scanQueue) != 0) {
            $rootPath = array_pop($scanQueue);

            // 过滤['.', '..']目录
            $paths = array_filter(scandir($rootPath), function ($path) {
                return !in_array($path, ['.', '..']);
            });

            foreach ($paths as $path) {
                // 拼接完整路径
                $fullPath = $rootPath . DIRECTORY_SEPARATOR . $path;
                // 如果是目录的话,合并到扫描队列中继续进行扫描
                if (is_dir($fullPath)) {
                    array_unshift($scanQueue, $fullPath);
                    continue;
                }

                // 如果不是空,进行过滤
                if (!empty($options['filterExt'])) {
                    $pathInfo = pathinfo($fullPath);
                    $ext = $pathInfo['extension'] ?? null;
                    if (in_array($ext, $options['filterExt'])) {
                        continue;
                    }
                }

                if ($options['callback'] instanceof Closure) {
                    // 经过callback处理之后为空的数据不作处理
                    $fullPath = $options['callback']($fullPath);
                    // 返回的只要不是字符串路径,不作处理
                    if (!is_string($fullPath)) {
                        continue;
                    }
                }

                array_push(static::$files, $fullPath);
            }
        }

        return static::$files;
    }

    /**
     * 目录拷贝,返回被拷贝的文件数,
     * @param $source string 源文件,填写绝对路径
     * @param $dest string 目标路径,填写绝对路径
     * @param $force bool 开启会每次强制覆盖原文件,false不进行覆盖,存在文件不做处理
     * @return int 拷贝的文件数
     * @author: Vencenty
     * @time: 2019/6/27 17:57
     */
    static function copy($source, $dest, $force = true)
    {
        static $counter = 0;
        $paths = array_filter(scandir($source), function ($file) {
            return !in_array($file, ['.', '..']);
        });

        foreach ($paths as $path) {
            // 要拷贝的源文件的完整路径
            $sourceFullPath = $source . DIRECTORY_SEPARATOR . $path;
            // 要拷贝到的文件的路径
            $destFullPath = $dest . DIRECTORY_SEPARATOR . $path;

            // 拷贝的目标地址如果是不是文件夹,那么说明文件夹不存在,那么首先创建文件夹
            if (is_dir($sourceFullPath)) {
                if (!is_dir($destFullPath)) {
                    mkdir($destFullPath);
                    chmod($destFullPath, 0755);
                }
                // 递归copy
                static::copy($sourceFullPath, $destFullPath, $force);
                continue;
            }

            // 不开启强制覆盖的话如果已经存在文件了那么直接跳过,不进行处理
            if (!$force && file_exists($destFullPath)) {
                continue;
            }

            // 每次copy成功文件计数器+1
            if (copy($sourceFullPath, $destFullPath)) {
                $counter++;
            }
        }

        return $counter;
    }
}
$path = realpath('../');
$r = Dir::scan($path, [
    'callback' => function ($file) {
        return filemtime($file) > strtotime('-1 day') ? $file : null; // 查找修改过的文件
    },
    'filterExt' => []
]);
//print_r($r);

$r = Dir::copy('C:\phpStudy\PHPTutorial\WWW\php\.idea', 'C:\phpStudy\PHPTutorial\WWW\php', true);
print_r($r);

项目中需要使用这两个功能,所以就写了这两个方法,其中scan方法的第二个参数options可以根据自己的需要进行扩展,

$r = Dir::scan($path, [
    'callback' => function ($file) {
        return filemtime($file) > strtotime('-1 day') ? $file : null; // 查找一天内修改过的文件
    },
    'filterExt' => ['php'] // 过滤所有PHP文件
]);

callback回调函数可以用来实现文件过滤的功能,文件类型查找等,具体场景具体分析
options参数相当于是扩展了函数配置项, 新的配置项会覆盖默认配置,相较于一个函数

static function scan($path, $callback, $filterExt) {} 

我更喜欢下面这种写法,更灵活一些

static function scan($path, $options) 
{
	$options = array_merge([
		'callback' => null,
		'filterExt' => [],
		'otherOptions' => null 
	], $options);	
}

Dir::copy($source, $dest, $force = true) 这个函数也很简单,就是带了一个强制覆盖和非强制覆盖的选项,自己实现了一下,也分享一下吧
就先这样~

你可能感兴趣的:(PHP常用函数库)