PHP foreach遍历多维数组实现方式


Posted in PHP onNovember 16, 2016

介绍
正常我们的foreach可以按顺序把一维数组里面每个 key => value 打印出来,但是如果是多维数组则需要循环在嵌套循环,或则递归实现,但是这些方式都不够灵活,因为在不确定该数组是几维的情况下,不可能永无止境的嵌套循环,如果采用递归到可以解决,但是如果只想使用foreach全部循环出来该如何实现?

实现方式 一
采用PHP本身自带的迭代器类 RecursiveIteratorIterator

$test_arr = array(1,2,3,array(4,'aa'=>5,6,array(7,'bb'=>8),9,10),11,12); 
  $arrayiter = new RecursiveArrayIterator($test_arr);
  $iteriter = new RecursiveIteratorIterator($arrayiter);
  //直接打印即可按照横向顺序打印出来
  foreach ($iteriter as $key => $val){ 
    echo $key.'=>'.$val; 
  } 
  //结果
  /* 
    0=>1
    1=>2 
    2=>3
    0=>4
    aa=>5
    2=>6
    0=>7
    bb=>8
    4=>9
    5=>10
    4=>11
    5=>12
 */

实现方式 二
自己实现一个类似于 RecursiveIteratorIterator 的迭代器类,实现多维数组横向打印功能

class foreachPrintfArr implements Iterator {
    //当前数组作用域
    private $_items; 
    private $_old_items;
    //保存每次执行数组环境栈
    private $_stack = array(); 

    public function __construct($data=array()){
      $this->_items = $data;
    }

    private function _isset(){
      $val = current($this->_items);

      if (empty($this->_stack) && !$val) {
        return false;
      } else {
        return true;
      }  
    }

    public function current() {
      $this->_old_items = null;
      $val = current($this->_items);

      //如果是数组则保存当前执行环境,然后切换到新的数组执行环境
      if (is_array($val)){
        array_push($this->_stack,$this->_items);
        $this->_items = $val;
        return $this->current();
      }

      //判断当前执行完成后是否需要切回上次执行环境
      //(1) 如果存在跳出继续执行
      //(2) 如果不存在且环境栈为空,则表示当前执行到最后一个元素
      //(3) 如果当前数组环境下一个元素不存在,则保存一下当前执行数组环境 $this->_old_items = $this->_items;
      //然后切换上次执行环境 $this->_items = array_pop($this->_stack) 继续循环, 直到当前数组环境下一个
      //元素不为空为止
      while (1) {
        if (next($this->_items)) {  
          prev($this->_items); break;
        } elseif (empty($this->_stack)) {
          end($this->_items); break;
        } else {
          end($this->_items);
          if (!$this->_old_items) 
            $this->_old_items = $this->_items;
          $this->_items = array_pop($this->_stack);
        }
      }

      return $val;
    }

    public function next() {
      next($this->_items);  
    }

    public function key() {
      // 由于 key() 函数执行在 current() 函数之后
      // 所以在 current() 函数切换执行环境 , 会导致切换之前的执行环境最后一个 key
      // 变成切换之后的key , 所以 $this->_old_items 保存一下切换之前的执行环境
      // 防止key打印出错
      return $this->_old_items ? key($this->_old_items) : key($this->_items);
    }

    public function rewind() {
      reset($this->_items);
    }

    public function valid() {                                       
      return $this->_isset();
    }
  }

内部执行方式

1、foreach 循环我们自定义的foreachPrintfArr类,会自动调用内部这5个方法 valid()、rewind()、key()、next()、current() 我们只需要实现这几个方法即可.

2、调用顺序:
第1次 => rewind -> valid -> current -> key
第2次~n次 =>  next -> valid -> current -> key

$test_arr = array(1,2,3,array(4,'aa'=>5,6,array(7,'bb'=>8),9,10),11,12);
   $iteriter = new foreachPrintfArr($test_arr);
   foreach ($iteriter as $key => $val){
     echo $key.'=>'.$val;
   } 
   //结果:
   /* 
   0=>1
   1=>2
   2=>3
   0=>4
   aa=>5
   2=>6
   0=>7
   bb=>8
   4=>9
   5=>10
   4=>11
   5=>12
   */

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
PHP5中MVC结构学习
Oct 09 PHP
全文搜索和替换
Oct 09 PHP
Win2003服务器安全加固设置--进一步提高服务器安全性
May 23 PHP
PHP入门学习的几个不错的实例代码
Jul 13 PHP
连接到txt文本的超链接,不直接打开而是点击后下载的处理方法
Jul 01 PHP
php将会员数据导入到ucenter的代码
Jul 18 PHP
Php中文件下载功能实现超详细流程分析
Jun 13 PHP
PHP 下载文件时如何自动添加bom头及解释BOM头和去掉bom头的方法
Jan 04 PHP
PHP模板引擎Smarty中变量的使用方法示例
Apr 11 PHP
php实现在站点里面添加邮件发送的功能
Apr 28 PHP
PHP中使用foreach()遍历二维数组的简单实例
Jun 13 PHP
PHP页面跳转操作实例分析(header方法)
Sep 28 PHP
php数据库操作model类(使用__call方法)
Nov 16 #PHP
php实现的简单数据库操作Model类
Nov 16 #PHP
iOS自定义提示弹出框实现类似UIAlertView的效果
Nov 16 #PHP
PHP中串行化用法示例
Nov 16 #PHP
PHP单态模式简单用法示例
Nov 16 #PHP
php实现替换手机号中间数字为*号及隐藏IP最后几位的方法
Nov 16 #PHP
php实现当前页面点击下载文件的实例代码
Nov 16 #PHP
You might like
用PHP编程语言开发动态WAP页面
2006/10/09 PHP
php静态文件生成类实例分析
2015/01/03 PHP
php正则表达式学习笔记
2015/11/13 PHP
php构造方法中析构方法在继承中的表现
2016/04/12 PHP
PHP重置数组为连续数字索引的几种方式总结
2018/03/12 PHP
使用ucenter实现多站点同步登录的讲解
2019/03/21 PHP
php文件后缀不强制为.php的实操方法
2019/09/18 PHP
JS实现简洁、全兼容的拖动层实例
2015/05/13 Javascript
Nodejs实战心得之eventproxy模块控制并发
2015/10/27 NodeJs
基于JavaScript实现定时跳转到指定页面
2016/01/01 Javascript
JavaScript基础重点(必看)
2016/07/09 Javascript
浅谈angularjs module返回对象的坑(推荐)
2016/10/21 Javascript
MUI顶部选项卡的用法(tab-top-webview-main)详解
2017/10/08 Javascript
浅谈JavaScript的innerWidth与innerHeight
2017/10/12 Javascript
Vue2.0中集成UEditor富文本编辑器的方法
2018/03/03 Javascript
jQuery实现文件编码成base64并通过AJAX上传的方法
2018/04/12 jQuery
js+html5 canvas实现ps钢笔抠图
2019/04/28 Javascript
微信小程序导航栏跟随滑动效果的实现代码
2019/05/14 Javascript
js实现碰撞检测
2021/01/29 Javascript
[01:32]寻找你心中的那团火 DOTA2 TI9火焰传递活动今日开启
2019/05/16 DOTA
浅析Python多线程下的变量问题
2015/04/28 Python
在Python程序中操作MySQL的基本方法
2015/07/29 Python
Django REST为文件属性输出完整URL的方法
2017/12/18 Python
python cs架构实现简单文件传输
2020/03/20 Python
python 将有序数组转换为二叉树的方法
2019/03/26 Python
如何将 awk 脚本移植到 Python
2019/12/09 Python
浅析与CSS3的loading动画加载相关的transition优化
2015/05/18 HTML / CSS
Rakuten Kobo台湾:电子书、eReaders和Reading应用程式
2017/11/24 全球购物
adidas瑞典官方网站:购买阿迪达斯鞋子和运动服
2019/12/11 全球购物
总经理职责
2013/12/22 职场文书
2014年公司迎新年活动方案
2014/02/24 职场文书
一年级语文下册复习计划
2015/01/17 职场文书
英语通知范文
2015/04/22 职场文书
钱学森电影观后感
2015/06/04 职场文书
中国式结婚:司仪主持词(范文)
2019/07/25 职场文书
Go语言设计模式之结构型模式
2021/06/22 Golang