PHP不用递归遍历目录下所有文件的代码


Posted in PHP onJuly 04, 2014

实现代码:

/**
 * PHP 非递归实现查询该目录下所有文件
 * @param unknown $dir
 * @return multitype:|multitype:string
 */
function scanfiles($dir) {
 if (! is_dir ( $dir ))
 return array ();
 
 // 兼容各操作系统
 $dir = rtrim ( str_replace ( '\\', '/', $dir ), '/' ) . '/';
 
 // 栈,默认值为传入的目录
 $dirs = array ( $dir );
 
 // 放置所有文件的容器
 $rt = array ();
 
 do {
 // 弹栈
 $dir = array_pop ( $dirs );
 
 // 扫描该目录
 $tmp = scandir ( $dir );
 
 foreach ( $tmp as $f ) {
  // 过滤. ..
  if ($f == '.' || $f == '..')
  continue;
  
  // 组合当前绝对路径
  $path = $dir . $f;
  
  
  // 如果是目录,压栈。
  if (is_dir ( $path )) {
  array_push ( $dirs, $path . '/' );
  } else if (is_file ( $path )) { // 如果是文件,放入容器中
  $rt [] = $path;
  }
 }
 
 } while ( $dirs ); // 直到栈中没有目录
 
 return $rt;
}

附另一篇:不用递归遍历目录下的文件

如果要遍历某个目录下的所有文件(包括子目录),最首先想到的思路就是用递归:先处理当前目录,再处理当前目录下的子目录。不用递归可不可以呢?以前学数据结构的时候看到过,递归其实是利用堆栈来实现的,递归的特点就是不断的调用自身,最后一次的调用是最先执行完的,倒数第二次调用是其次执行完的,依次类推,最初的调用是最后执行完的。如果理解了递归的原理,其实就可以把所有用递归的实现转化为非递归的实现。

用非递归方式遍历某个目录下的所有文件,思路主要分三步:

1. 创建一个数组,将要遍历的这个目录放入;(其实就是创建了一个栈)
2. 循环处理这个数组,循环结束的条件是数组为空;
3. 每次循环,处理数组中的一个元素,并将元素删除,如果这个元素是目录,则将目录下所有的子元素加入数组;

按照这种思路写出的代码如下:

/**
 * 遍历某个目录下的所有文件
 * @param string $dir
 */
function scanAll($dir)
{
  $list = array();
  $list[] = $dir;

  while (count($list) > 0)
  {
    //弹出数组最后一个元素
    $file = array_pop($list);

    //处理当前文件
    echo $file."\r\n";

    //如果是目录
    if (is_dir($file))
    {
      $children = scandir($file);
      foreach ($children as $child)
      {
        if ($child !== '.' && $child !== '..')
        {
          $list[] = $file.'/'.$child;
        }
      }
    }
  }
}

这里我并没有认为递归有多大的缺点,事实上很多情况下,用递归来设计还是非常简洁可读的,至于效率问题,除非在递归深度特别大的时候,才会有影响。

以下是用递归的实现,作为对比:

/**
 * 遍历某个目录下的所有文件(递归实现)
 * @param string $dir
 */
function scanAll2($dir)
{
  echo $dir."\r\n";

  if (is_dir($dir))
  {
    $children = scandir($dir);
    foreach ($children as $child)
    {
      if ($child !== '.' && $child !== '..')
      {
        scanAll2($dir.'/'.$child);
      }
    }
  }
}

运行发现,两个函数的结果略有不同,主要表现在打印的顺序上。函数一运行结果的顺序是倒着的,是因为压栈的顺序正好和scandir出来的顺序相反了,可以将第21行改一下:

$children = array_reverse(scandir($file));

这样出来结果就完全相同了。

PHP 相关文章推荐
php学习之 认清变量的作用范围
Jan 26 PHP
PHP定时自动生成静态HTML的实现代码
Jun 20 PHP
抓取并下载CSS中所有图片文件的php代码
Sep 26 PHP
php的POSIX 函数以及进程测试的深入分析
Jun 03 PHP
浅析Yii中使用RBAC的完全指南(用户角色权限控制)
Jun 20 PHP
浅析php面向对象public private protected 访问修饰符
Jun 30 PHP
php获取目录所有文件并将结果保存到数组(实例)
Oct 25 PHP
php+mysql不用递归实现的无限级分类实例(非递归)
Jul 08 PHP
PHP学习笔记(二):变量详解
Apr 17 PHP
[原创]php简单隔行变色功能实现代码
Jul 09 PHP
PHP 多任务秒级定时器的实现方法
May 13 PHP
PHP Trait代码复用类与多继承实现方法详解
Jun 17 PHP
对于ThinkPHP框架早期版本的一个SQL注入漏洞详细分析
Jul 04 #PHP
PHP+Memcache实现wordpress访问总数统计(非插件)
Jul 04 #PHP
php+memcache实现的网站在线人数统计代码
Jul 04 #PHP
PHP轻量级数据库操作类Medoo增加、删除、修改、查询例子
Jul 04 #PHP
CodeIgniter安全相关设置汇总
Jul 03 #PHP
php使用pack处理二进制文件的方法
Jul 03 #PHP
PHP源码分析之变量的存储过程分解
Jul 03 #PHP
You might like
PHP fastcgi模式上传大文件(大约有300多K)报错
2014/09/28 PHP
ThinkPHP实现非标准名称数据表快速创建模型的方法
2014/11/29 PHP
PHP中使用GD库绘制折线图 折线统计图的绘制方法
2015/11/09 PHP
PHP通过CURL实现定时任务的图片抓取功能示例
2016/10/03 PHP
详解php中空字符串和0之间的关系
2016/10/23 PHP
浅析PHP7 的垃圾回收机制
2019/09/06 PHP
js中访问html中iframe的文档对象的代码[IE6,IE7,IE8,FF]
2011/01/08 Javascript
jQuery中:visible选择器用法实例
2014/12/30 Javascript
jquery+CSS3实现淘宝移动网页菜单效果
2015/08/31 Javascript
js图片轮播手动切换效果
2015/11/10 Javascript
AngularJs实现ng1.3+表单验证
2015/12/10 Javascript
JS简单生成两个数字之间随机数的方法
2016/08/03 Javascript
微信小程序  wx.request合法域名配置详解
2016/11/23 Javascript
JavaScript、C# URL编码、解码总结
2017/01/21 Javascript
react路由配置方式详解
2017/08/07 Javascript
Vue中引入样式文件的方法
2017/08/18 Javascript
javascript数组拍平方法总结
2018/01/20 Javascript
layui表格checkbox选择全选样式及功能的实例
2018/03/07 Javascript
JS获取并处理php数组的方法实例分析
2018/09/04 Javascript
JS实现商品橱窗特效
2020/01/09 Javascript
JavaScript实现省份城市的三级联动
2020/02/11 Javascript
[41:05]Serenity vs Pain 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
[40:04]Secret vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.23
2019/09/05 DOTA
python实现绘制树枝简单示例
2014/07/24 Python
Random 在 Python 中的使用方法
2018/08/09 Python
解决python os.mkdir创建目录失败的问题
2018/10/16 Python
Python测试模块doctest使用解析
2019/08/10 Python
Python中six模块基础用法
2019/12/08 Python
纯CSS3实现给头像加个光芒四射且旋转的背景动画效果
2014/05/07 HTML / CSS
北京某科技有限公司C# .net笔试题
2014/09/27 面试题
《最大的“书”》教学反思
2014/02/14 职场文书
应届生求职信
2014/05/31 职场文书
办公室主任四风问题对照检查材料思想汇报
2014/09/28 职场文书
2014年小学安全工作总结
2014/12/04 职场文书
JUnit5常用注解的使用
2021/07/02 Java/Android
node.js使用express-fileupload中间件实现文件上传
2021/07/16 Javascript