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 相关文章推荐
建立动态的WML站点(三)
Oct 09 PHP
一个分页的论坛
Oct 09 PHP
php目录管理函数小结
Sep 10 PHP
自己写的兼容低于PHP 5.5版本的array_column()函数
Oct 24 PHP
PHP实现的简单日历类
Nov 29 PHP
PHP中让curl支持sock5的代码实例
Jan 21 PHP
PHP中使用imagick生成PSD文件缩略图教程
Jan 26 PHP
php生成图片验证码的实例讲解
Aug 03 PHP
详解Window7 下开发php扩展
Dec 31 PHP
PHP基于SPL实现的迭代器模式示例
Apr 22 PHP
php命令行写shell实例详解
Jul 19 PHP
PHP设计模式之PHP迭代器模式讲解
Mar 22 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中curl_multi的应用
2013/07/17 PHP
php将字符串转化成date存入数据库的两种方式
2014/04/28 PHP
PHP生成不重复随机数的方法汇总
2014/11/19 PHP
php操作mongoDB实例分析
2014/12/29 PHP
PHP获取当前URL路径的处理方法(适用于多条件筛选列表)
2017/02/10 PHP
PHP+AJAX 投票器功能
2017/11/11 PHP
php遍历目录下文件并按修改时间排序操作示例
2019/07/12 PHP
瀑布流布局代码一例
2014/04/11 Javascript
jQuery操作select下拉框的text值和value值的方法
2014/05/31 Javascript
jQuery响应鼠标事件并隐藏与显示input默认值
2014/08/24 Javascript
jQuery 判断元素整理汇总
2017/02/28 Javascript
JS数组搜索之折半搜索实现方法分析
2017/03/27 Javascript
Angular.JS去掉访问路径URL中的#号详解
2017/03/30 Javascript
js每隔两秒输出数组中的一项(实例)
2017/05/28 Javascript
angularjs定时任务的设置与清除示例
2017/06/02 Javascript
node.js中grunt和gulp的区别详解
2017/07/17 Javascript
[43:49]LGD vs CHAOS 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
Python中使用第三方库xlrd来读取Excel示例
2015/04/05 Python
Python用list或dict字段模式读取文件的方法
2017/01/10 Python
Python入门之三角函数atan2()函数详解
2017/11/08 Python
Python 使用type来定义类的实现
2019/11/19 Python
python错误调试及单元文档测试过程解析
2019/12/19 Python
vue常用指令代码实例总结
2020/03/16 Python
详解Python直接赋值,深拷贝和浅拷贝
2020/07/09 Python
Python实现自动装机功能案例分析
2020/10/22 Python
一些Solaris面试题
2013/03/22 面试题
医学护理系毕业生求职信
2013/10/01 职场文书
机关财务管理制度
2014/01/17 职场文书
培训主管的职业生涯规划
2014/03/06 职场文书
让世界充满爱演讲稿
2014/05/24 职场文书
军人离婚协议书样本
2014/10/21 职场文书
残联2016年全国助残日活动总结
2016/04/01 职场文书
古诗之感恩老师
2019/10/24 职场文书
Python 读写 Matlab Mat 格式数据的操作
2021/05/19 Python
海弦WR-800F
2022/04/05 无线电
table设置超出部分隐藏,鼠标移上去显示全部内容的方法
2022/12/24 HTML / CSS