php用栈遍历目录和文件,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可以根据自己的需要进行扩展,

$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) 这个函数也很简单,就是带了一个强制覆盖和非强制覆盖的选项,自己实现了一下,简单记录一下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值