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 相关文章推荐
第四节 构造函数和析构函数 [4]
Oct 09 PHP
解析php中const与define的应用区别
Jun 18 PHP
用PHP和Shell写Hadoop的MapReduce程序
Apr 15 PHP
使用ob系列函数实现PHP网站页面静态化
Aug 13 PHP
ThinkPHP分页实例
Oct 15 PHP
ThinkPHP3.2.2实现持久登录(记住我)功能的方法
May 16 PHP
PHP获取客户端及服务器端IP的封装类
Jul 21 PHP
PHP判断用户是否已经登录(跳转到不同页面或者执行不同动作)
Sep 22 PHP
PHP 实现字符串翻转(包含中文汉字)的实现代码
Apr 01 PHP
PHP编程实现脚本异步执行的方法
Aug 09 PHP
php实现获取农历(阴历)、节日、节气的类与用法示例
Nov 20 PHP
PHP类的自动加载与命名空间用法实例分析
Jun 05 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
利用js调用后台php进行数据处理原码
2006/10/09 PHP
PHPMailer邮件类利用smtp.163.com发送邮件方法
2008/09/11 PHP
解析link_mysql的php版
2013/06/30 PHP
PHP 登录完成后如何跳转上一访问页面
2014/01/14 PHP
PHP处理Json字符串解码返回NULL的解决方法
2014/09/01 PHP
php延迟静态绑定实例分析
2015/02/08 PHP
php自定义时间转换函数示例
2016/12/07 PHP
php-app开发接口加密详解
2018/04/18 PHP
使用jQuery.Validate进行客户端验证(初级篇) 不使用微软验证控件的理由
2010/06/28 Javascript
(jQuery,mootools,dojo)使用适合自己的编程别名命名
2010/09/14 Javascript
JavaScript控制按钮可用或不可用的方法
2015/04/03 Javascript
全面了解javascript中的错误处理机制
2016/07/18 Javascript
基于JavaScript实现鼠标箭头移动图片跟着移动
2016/08/30 Javascript
jQuery根据ID、CLASS、等获取对象的实例
2016/12/04 Javascript
jquery仿ps颜色拾取功能
2017/03/08 Javascript
微信小程序开发教程之增加mixin扩展
2017/08/09 Javascript
Vue.js用法详解
2017/11/13 Javascript
Element input树型下拉框的实现代码
2018/12/21 Javascript
Vue从TodoList中学父子组件通信
2019/02/05 Javascript
JavaScript this在函数中的指向及实例详解
2019/10/14 Javascript
浅谈webpack和webpack-cli模块源码分析
2020/01/19 Javascript
JavaScript中数组去重的5种方法
2020/07/04 Javascript
详解Python中的静态方法与类成员方法
2017/02/28 Python
Python从单元素字典中获取key和value的实例
2018/12/31 Python
在python中实现强制关闭线程的示例
2019/01/22 Python
Python 一键制作微信好友图片墙的方法
2019/05/16 Python
The Hut德国站点:时装、家居用品、美容等
2016/09/23 全球购物
J2EE包括哪些技术
2016/11/25 面试题
办公室助理岗位职责
2013/12/25 职场文书
旷课检讨书3000字
2014/02/04 职场文书
企业军训感想
2014/02/07 职场文书
专题组织生活会方案
2014/06/15 职场文书
“四风”问题整改措施和努力方向
2014/09/20 职场文书
员工保密协议书
2014/09/27 职场文书
整改落实情况汇报材料
2014/10/29 职场文书
商场圣诞节活动总结
2015/05/06 职场文书