PHP基于迭代实现文件夹复制、删除、查看大小等操作的方法


Posted in PHP onAugust 11, 2017

本文实例讲述了PHP基于迭代实现文件夹复制、删除、查看大小等操作的方法。分享给大家供大家参考,具体如下:

前面一篇 PHP递归实现文件夹的复制、删除、查看大小操作 分析了递归操作使用技巧,这里再来分析一下迭代的操作技巧。

“既然递归能很好的解决,为什么还要用迭代呢”?主要的原因还是效率问题……

递归的概念是函数调用自身,把一个复杂的问题分解成与其相似的多个子问题来解决,可以极大的减少代码量,使得程序看起来非常优雅。

由于系统要为每次函数调用分配运行空间,并使用压栈予以记录。在函数调用结束后,系统需要释放空间,并弹栈恢复断点。所以递归的消耗还是比较大的。

即使语言设计时已经将函数调用优化的极度完美,达到可以忽略递归造成的资源浪费,但是递归的深度仍然会受到系统栈容量的限制,否则将会抛出 StackOverflowError 错误。

而迭代能很好的利用计算机适合做重复操作的特点,并且从理论上说,所有的递归函数都可以转换为迭代函数,所以尽量能不用递归就不用递归,能用迭代代替就用迭代代替。

查看文件夹大小

迭代的思路是让计算机对一组指令进行重复执行,在每次执行这组指令时,都从变量的原值推出其它的新值……重复这一过程直到达到结束条件或没有新值产生。

由于递归相当于循环加堆栈,所以可以在迭代中使用堆栈来进行递归和迭代的转换。

/**
 * 文件夹大小
 * @param $path
 * @return int
 */
function dirsize($path)
{
  /* 初始条件 */
  $size = 0;
  $stack = array();
  if (file_exists($path)) {
    $path = realpath($path) . '/';
    array_push($stack, '');
  } else {
    return -1;
  }
  /* 迭代条件 */
  while (count($stack) !== 0) {
    $dir = array_pop($stack);
    $handle = opendir($path . $dir);
    /* 执行过程 */
    while (($item = readdir($handle)) !== false) {
      if ($item == '.' || $item == '..') continue;
      $_path = $path . $dir . $item;
      if (is_file($_path)) $size += filesize($_path);
      /* 更新条件 */
      if (is_dir($_path)) array_push($stack, $dir . $item . '/');
    }
    closedir($handle);
  }
  return $size;
}

复制文件夹

迭代和递归都具有初始化变量、判断结束条件、执行实际操作、产生新变量这四个步骤,只不过所在的位置不同罢了。

比如初始化变量这一步骤,在迭代中是位于函数的开始部分,而在递归中是指其他函数传递参数这一过程;

判断结束条件这一步骤,在迭代中用于判断循环是否继续,在递归中用于判断递归的结束位置;

执行实际操作在递归和迭代中都是函数的核心部分,位于产生新变量步骤之前;

产生新变量在迭代中是迭代继续的条件,在递归中是下一次递归的基础,由于产生了新变量才使得递归或迭代继续进行。

/**
 * 复制文件夹
 * @param $source
 * @param $dest
 * @return string
 */
function copydir($source, $dest)
{
  /* 初始条件 */
  $stack = array();
  $target = '';
  if (file_exists($source)) {
    if (!file_exists($dest)) mkdir($dest);
    $source = realpath($source) . '/';
    $dest = realpath($dest) . '/';
    $target = realpath($dest);
    array_push($stack, '');
  }
  /* 迭代条件 */
  while (count($stack) !== 0) {
    $dir = array_pop($stack);
    $handle = opendir($source . $dir);
    if (!file_exists($dest . $dir)) mkdir($dest . $dir);
    /* 执行过程 */
    while (($item = readdir($handle)) !== false) {
      if ($item == '.' || $item == '..') continue;
      $_source = $source . $dir . $item;
      $_dest = $dest . $dir . $item;
      if (is_file($_source)) copy($_source, $_dest);
      /* 更新条件 */
      if (is_dir($_source)) array_push($stack, $dir . $item . '/');
    }
    closedir($handle);
  }
  return $target;
}

删除文件夹

抛开语言特性影响性能最多的就是冗余代码了,冗余代码通常是由于设计不到位而产生的。

多数情况下递归要比迭代冗余代码更多,这也是造成递归效率低的一大因素。

但当递归代码足够简练,冗余度足够低时,迭代的性能未必就比递归高。

比如这个用迭代实现的文件夹删除函数,速度就比递归要慢20%,主要原因是空文件夹的判断,在递归中当文件夹没有子文件夹时,函数会直接删除所有文件和当前文件夹,递归结束。

在迭代中即使文件夹为空也需要将其存入堆栈,下次迭代时再判断是否为空,之后才能删除。这就相比递归多了判断文件为空、存入堆栈、取出迭代等冗余操作,所以处理速度会比递归更慢。

/**
 * 删除文件夹
 * @param $path
 * @return bool
 */
function rmdirs($path)
{
  /* 初始化条件 */
  $stack = array();
  if (!file_exists($path)) return false;
  $path = realpath($path) . '/';
  array_push($stack, '');
  /* 迭代条件 */
  while (count($stack) !== 0) {
    $dir = end($stack);
    $items = scandir($path . $dir);
    /* 执行过程 */
    if (count($items) === 2) {
      rmdir($path . $dir);
      array_pop($stack);
      continue;
    }
    /* 执行过程 */
    foreach ($items as $item) {
      if ($item == '.' || $item == '..') continue;
      $_path = $path . $dir . $item;
      if (is_file($_path)) unlink($_path);
      /* 更新条件 */
      if (is_dir($_path)) array_push($stack, $dir . $item . '/');
    }
  }
  return !(file_exists($path));
}

查看执行时间

这是一个查看代码执行时间(毫秒数)的函数,通过回调方式执行目标代码(或函数),最终计算出执行的时间(毫秒)。通过这个工具可以对比函数之间的性能差距,非常简单实用的一个小工具。

/**
 * 函数执行毫秒数
 * @param $func
 * @return int
 */
function exec_time($func)
{
  $start = explode(' ', microtime());
  $func();// 执行耗时操作
  $end = explode(' ', microtime());
  $sec_time = floatval($end[0]) - floatval($start[0]);
  $mic_time = floatval($end[1]) - floatval($start[1]);
  return intval(($sec_time + $mic_time) * 1000);
}
echo exec_time(function () {
  /* 执行的耗时操作 */
});

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
在PHP模板引擎smarty生成随机数的方法和math函数详解
Apr 24 PHP
php使用pack处理二进制文件的方法
Jul 03 PHP
php socket实现的聊天室代码分享
Aug 16 PHP
PHP实现将HTML5中Canvas图像保存到服务器的方法
Nov 28 PHP
试用php中oci8扩展
Jun 18 PHP
PHP 的比较运算与逻辑运算详解
May 12 PHP
PHP生成图像验证码的方法小结(2种方法)
Jul 18 PHP
Yii2实现log输出到file及database的方法
Nov 12 PHP
Win7环境下Apache连接MySQL提示连接已重置的解决办法
May 09 PHP
ThinkPHP3.2框架自带分页功能实现方法示例
May 13 PHP
php函数式编程简单示例
Aug 08 PHP
phpStorm2020 注册码
Sep 17 PHP
基于Laravel5.4实现多字段登录功能方法示例
Aug 11 #PHP
PHP递归实现文件夹的复制、删除、查看大小操作示例
Aug 11 #PHP
关于PHP中协程和阻塞的一些理解与思考
Aug 11 #PHP
如何利用预加载优化Laravel Model查询详解
Aug 11 #PHP
PHP实现的自定义图像居中裁剪函数示例【测试可用】
Aug 11 #PHP
Redis在Laravel项目中的应用实例详解
Aug 11 #PHP
PHP验证码无法显示的原因及解决办法
Aug 11 #PHP
You might like
十天学会php之第五天
2006/10/09 PHP
php设置允许大文件上传示例代码
2014/03/10 PHP
Thinkphp调用Image类生成缩略图的方法
2015/03/07 PHP
PHP基于imagick扩展实现合成图片的两种方法【附imagick扩展下载】
2017/11/14 PHP
js 延迟加载 改变JS的位置加快网页加载速度
2012/12/11 Javascript
JS简单判断字符在另一个字符串中出现次数的2种常用方法
2017/04/20 Javascript
妙用Angularjs实现表格按指定列排序
2017/06/23 Javascript
iframe高度自适应及隐藏滚动条的实例详解
2017/09/29 Javascript
详解javascript中的变量提升和函数提升
2018/05/24 Javascript
angular2实现统一的http请求头方法
2018/08/13 Javascript
微信小程序图表插件wx-charts用法实例详解
2019/05/20 Javascript
jquery.tagsinput.js实现记录checkbox勾选的顺序
2019/09/21 jQuery
[01:06:43]完美世界DOTA2联赛PWL S3 PXG vs GXR 第二场 12.19
2020/12/24 DOTA
Python接收Gmail新邮件并发送到gtalk的方法
2015/03/10 Python
python dataframe常见操作方法:实现取行、列、切片、统计特征值
2018/06/09 Python
python使用Matplotlib绘制分段函数
2018/09/25 Python
10分钟教你用Python实现微信自动回复功能
2018/11/28 Python
selenium+python自动化测试之页面元素定位
2019/01/23 Python
python 标准差计算的实现(std)
2019/07/29 Python
python中web框架的自定义创建
2019/09/08 Python
python tkinter图形界面代码统计工具(更新)
2019/09/18 Python
Python 字典中的所有方法及用法
2020/06/10 Python
python利用paramiko实现交换机巡检的示例
2020/09/22 Python
Pycharm在指定目录下生成文件和删除文件的实现
2020/12/28 Python
Perfume’s Club德国官网:在线购买香水
2019/04/08 全球购物
伦敦新晋轻奢耳饰潮牌:Tada & Toy
2020/05/25 全球购物
牵手50香港:专为黄金岁月的单身人士而设的交友网站
2020/08/14 全球购物
计算机网络毕业生自荐信
2013/10/01 职场文书
学习优秀党员杨宗兴先进事迹材料思想汇报
2014/09/14 职场文书
检察院对照“四风”认真查找问题落实整改措施
2014/09/26 职场文书
2014最新股权信托合同协议书
2014/11/18 职场文书
2015年世界无烟日演讲稿
2015/03/18 职场文书
清洁工工作总结
2015/08/11 职场文书
python开发实时可视化仪表盘的示例
2021/05/07 Python
python 中[0]*2与0*2的区别说明
2021/05/10 Python
pytorch 权重weight 与 梯度grad 可视化操作
2021/06/05 Python