<?php class Dir { /** * 扫描目录下全部文件, * @var array */ protected static $files = []; public static $ret = []; /** * 扫描目录路径 * @param $path string 带扫描的路径 * @param array $options 要附加的选项,后面能够根据本身需求扩展 * @return array * @author: Vencenty */ 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 */ 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
能够根据本身的须要进行扩展,php
$r = Dir::scan($path, [ 'callback' => function ($file) { return filemtime($file) > strtotime('-1 day') ? $file : null; // 查找一天内修改过的文件 }, 'filterExt' => ['php'] // 过滤全部PHP文件 ]);
callback
回调函数能够用来实现文件过滤的功能,文件类型查找等,具体场景具体分析options
参数至关因而扩展了函数配置项, 新的配置项会覆盖默认配置,相较于一个函数ide
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)
这个函数也很简单,就是带了一个强制覆盖和非强制覆盖的选项,本身实现了一下,简单记录一下idea