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 相关文章推荐
PHP 时间转换Unix时间戳代码
Jan 22 PHP
php数组函数序列之array_key_exists() - 查找数组键名是否存在
Oct 29 PHP
探讨GDFONTPATH能否被winxp下的php支持
Jun 21 PHP
php使用Jpgraph绘制简单X-Y坐标图的方法
Jun 10 PHP
8个PHP数组面试题
Jun 23 PHP
Netbeans 8.2与PHP相关的新特性介绍
Oct 08 PHP
PHP之将POST数据转化为字符串的实现代码
Nov 03 PHP
详解Yii2.0使用AR联表查询实例
Jun 16 PHP
php记录搜索引擎爬行记录的实现代码
Mar 02 PHP
php删除二维数组中的重复值方法
Mar 12 PHP
PHP根据key删除数组中指定的元素
Feb 28 PHP
php 使用expat方式解析xml文件操作示例
Nov 26 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 zip文件解压类代码
2009/12/02 PHP
PHP实现补齐关闭的HTML标签
2016/03/22 PHP
PHP7 新特性详细介绍
2016/09/06 PHP
PHP实现将上传图片自动缩放到指定分辨率,并保持清晰度封装类示例
2019/06/17 PHP
js动画(animate)简单引擎代码示例
2012/12/04 Javascript
快速解决FusionCharts联动的中文乱码问题
2013/12/04 Javascript
最流行的Node.js精简型和全栈型开发框架介绍
2015/02/26 Javascript
ECMAScript6中Map/WeakMap详解
2015/06/12 Javascript
javascript原型继承工作原理和实例详解
2016/04/07 Javascript
第九篇Bootstrap导航菜单创建步骤详解
2016/06/21 Javascript
javascript宿主对象之window.navigator详解
2016/09/07 Javascript
jQuery实现表格奇偶行显示不同背景色 就这么简单
2017/03/13 Javascript
深入理解Vue2.x的虚拟DOM diff原理
2017/09/27 Javascript
jQuery实现获取table中鼠标click点击位置行号与列号的方法
2017/10/09 jQuery
基于element-ui的rules中正则表达式
2018/09/04 Javascript
详解如何解决vue开发请求数据跨域的问题(基于浏览器的配置解决)
2018/11/12 Javascript
微信小程序学习笔记之表单提交与PHP后台数据交互处理图文详解
2019/03/28 Javascript
Layui弹出层 加载 做编辑页面的方法
2019/09/16 Javascript
js实现秒表计时器
2019/12/16 Javascript
Python中Collection的使用小技巧
2014/08/18 Python
Python常见字符串操作函数小结【split()、join()、strip()】
2018/02/02 Python
Python文本处理之按行处理大文件的方法
2018/04/09 Python
Python3基于sax解析xml操作示例
2018/05/22 Python
python用插值法绘制平滑曲线
2021/02/19 Python
Python脚本去除文件的只读性操作
2020/03/05 Python
Python基于wordcloud及jieba实现中国地图词云图
2020/06/09 Python
CSS3 选择器 属性选择器介绍
2012/01/21 HTML / CSS
CSS3属性 line-clamp控制文本行数的使用
2020/03/19 HTML / CSS
amazeui时间组件的实现示例
2020/08/18 HTML / CSS
Tostadora意大利:定制T恤
2019/04/08 全球购物
千元咖啡店的创业计划书范文
2013/12/29 职场文书
纪检干部对照检查材料
2014/08/22 职场文书
幼儿园父亲节活动总结
2015/02/12 职场文书
酒店财务部岗位职责
2015/04/14 职场文书
上班旷工检讨书
2015/08/15 职场文书
win11怎么消除图标小盾牌?win11消除图标小盾牌解决方法
2022/08/05 数码科技