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转成EXE文件
Oct 09 PHP
php中目录,文件操作详谈
Mar 19 PHP
php获取某个目录大小的代码
Sep 10 PHP
PHP性能优化工具篇Benchmark类调试执行时间
Dec 06 PHP
PHP 验证码不显示只有一个小红叉的解决方法
Sep 30 PHP
一个PHP二维数组排序的函数分享
Jan 17 PHP
php快递单号查询接口使用示例
May 05 PHP
mac下Apache + MySql + PHP搭建网站开发环境
Jun 02 PHP
php实现删除空目录的方法
Mar 16 PHP
phpinfo()中Loaded Configuration File(none)的解决方法
Jan 16 PHP
PHP安装memcache扩展的步骤讲解
Feb 14 PHP
Laravel框架文件上传功能实现方法示例
Apr 16 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函数的方法
2013/11/13 PHP
ThinkPHP添加更新标签的方法
2014/12/05 PHP
PHP curl使用实例
2015/07/02 PHP
php使用Imagick生成图片的方法
2015/07/31 PHP
thinkPHP实现多字段模糊匹配查询的方法
2016/12/01 PHP
PHP7 mongoDB扩展使用的方法分享
2019/05/02 PHP
js 动态添加标签(新增一行,其实很简单,就是几个函数的应用)
2009/03/26 Javascript
深入理解js数组的sort排序
2016/05/28 Javascript
javascript经典特效分享 手风琴、轮播图、图片滑动
2016/09/14 Javascript
用Vue.js实现监听属性的变化
2016/11/17 Javascript
微信小程序开发教程-手势解锁实例
2017/01/06 Javascript
Vue2.0表单校验组件vee-validate的使用详解
2017/05/02 Javascript
Nodejs回调加超时限制两种实现方法
2017/06/09 NodeJs
Ionic + Angular.js实现验证码倒计时功能的方法
2017/06/12 Javascript
vue中动态添加class类名的方法
2018/09/05 Javascript
jQuery实现的自定义轮播图功能详解
2018/12/28 jQuery
深入了解Hybrid App技术的相关知识
2019/07/17 Javascript
layui监听下拉选框选中值变化的方法(包含监听普通下拉选框)
2019/09/24 Javascript
JavaScript随机数的组合问题案例分析
2020/05/16 Javascript
Vue + element 实现多选框组并保存已选id集合的示例代码
2020/06/03 Javascript
Python输出汉字字库及将文字转换为图片的方法
2016/06/04 Python
Python基于动态规划算法解决01背包问题实例
2017/12/06 Python
Python常见字符串操作函数小结【split()、join()、strip()】
2018/02/02 Python
python 多线程中子线程和主线程相互通信方法
2018/11/09 Python
Python+AutoIt实现界面工具开发过程详解
2019/08/07 Python
关于numpy中eye和identity的区别详解
2019/11/29 Python
sklearn-SVC实现与类参数详解
2019/12/10 Python
Python实现图像去噪方式(中值去噪和均值去噪)
2019/12/18 Python
如何将你的应用迁移到Python3的三个步骤
2019/12/22 Python
python 实现屏幕录制示例
2019/12/23 Python
解决Django no such table: django_session的问题
2020/04/07 Python
python Autopep8实现按PEP8风格自动排版Python代码
2021/03/02 Python
资料员岗位职责
2013/11/17 职场文书
文明寄语大全
2014/04/11 职场文书
《真想变成大大的荷叶》教学反思
2014/04/14 职场文书
win sever 2022如何占用操作主机角色
2022/06/25 Servers