PHP多维数组元素操作类的方法


Posted in PHP onNovember 14, 2016

我的框架里面一个多维数组元素操作类,主要用于读取数组中配置数据,可以通过字符串节点的方式:a.b.c 来获取和设置元素,以及多维数组的覆盖,有需求的可以参考下吧!

<?php
/**
 * Created by PhpStorm.
 * User: ZHOUZ
 * Date: 14-5-25
 * Time: 下午5:32
 */

namespace Snail\Component;

/**
 * 多维数组节点读写
 * Class Node
 * @package Snail\Component
 */
class Node extends AComponent
{
  /**
   * 多维数组节点分隔符
   * @var string
   */
  const SP = '.';

  /**
   * 将非字符串类型数据生成字符串节点
   * <code>
   * Node::create(array('a', 'b', 1, true)) => 'a.b.1.1'
   * Node::create('a', 'b', null, false)  => 'a.b'
   * </code>
   * @param mixed $nodes 支持数组、任意参数个数
   * @return string
   */
  public static function create($nodes) {
    ! is_array($nodes) && $nodes = func_get_args();
    return join(static::SP, array_filter(array_map('strval', $nodes)));
  }

  /**
   * 获取多维数组节点转化为数组键名
   * @param string $node
   * @return array
   */
  public static function explode($node) {
    return explode(static::SP, $node);
  }

  /**
   * 设置多维数组节点值
   * 注意:
   * 由于 PHP 数组数值键名长度只支持 int 的最大长度,
   * 为避免出现覆盖等混乱现象,所有节点在转化为键名时都将
   * 强制被转换为字符串类型
   * @param array & $arr 引用被操作数组的内存地址
   * @param string $node 节点路径, 如: a.b.c => $arr['a']['b']['c'];
   * @param mixed $value
   * @return void
   */
  public static function set(array & $arr, $node, $value = null) {
    $arr = $arr2 = (array) $arr;
    $keys = static::explode($node);
    foreach ($keys as $key) {
      $key = strval($key);
      if (isset($arr[$key])) {
        $arr = & $arr[$key];
      } else {
        $arr[$key] = array();
        $arr = & $arr[$key];
      }
    }
    $arr = $value;
  }

  /**
   * 获取多维数组指定节点值
   * @param array & $arr 引用被操作数组的内存地址
   * @param string $node 节点路径, 如: a.b.c => $arr['a']['b']['c'];
   * @param null|mixed $default 若节点不存在时返回该默认值
   * @return mixed
   */
  public static function get(array & $arr, $node, $default = null) {
    if (empty($arr)) return $default;
    $keys = static::explode($node);
    foreach ($keys as $key) {
      $key = strval($key);
      if (isset($arr[$key])) {
        $arr = & $arr[$key];
      } else {
        return $default;
      }
    }
    return $arr;
  }

  /**
   * 将第二个多维数组覆盖或添加到第一个多维数组进行合并
   * @param array & $arraySrc 引用被更新的数组
   * @param array & $arrayReplace 引用需要合并的数据
   * @return void 地址操作无返回值
   */
  public static function merge(array & $arraySrc, array & $arrayReplace) {
    if (empty($arrayReplace)) return;
    foreach ($arrayReplace as $k=>& $v) {
      if (is_array($v) && isset($arraySrc[$k])) {
        static::merge($arraySrc[$k], $v);
      } else {
        $arraySrc[$k] = $v;
      }
    }
  }

  /**
   * 判断多维数组中是否存在指定节点,
   * 结果同 isset 关键字 (若存在键但值为 NULL 则也会返回 false)
   * @param array & $arr 引用原数组
   * @param string $node
   * @return bool
   */
  public static function has(array & $arr, $node) {
    if (empty($arr)) return false;
    $keys = static::explode($node);
    foreach ($keys as $key) {
      $key = strval($key);
      if (isset($arr[$key])) {
        $arr = & $arr[$key];
      } else {
        return false;
      }
    }
    return true;
  }

  /**
   * 判断多维数组中是否存在指定键
   * @param array & $arr 引用原数组
   * @param string $node
   * @return bool
   */
  public static function hasKey(array & $arr, $node) {
    if (empty($arr)) return false;
    $keys = static::explode($node);
    foreach ($keys as $key) {
      $key = strval($key);
      if (array_key_exists($key, $arr)) {
        $arr = & $arr[$key];
      } else {
        return false;
      }
    }
    return true;
  }

  /**
   * 注销数组中的指定节点元素
   * @param array $arr
   * @param string $node
   * @return void
   */
  public static function clear(array & $arr, $node) {
    if (empty($arr)) return;
    $keys = static::explode($node);
    foreach ($keys as $key) {
      $key = strval($key);
      if (isset($arr[$key])) {
        $arr = & $arr[$key];
      } else {
        return; // 指定节点不存在亦认为是成功
      }
    }
    $arr = null;
    unset($arr);
  }
}

下面举个栗子:

<?php
echo '<pre>';
// 测试数组1
$arr1 = ['a'=>['b'=>['c'=>['d'=>['e'=>['f'=>'http://blog.csdn.net/zhouzme']]]]]];
// 测试数组2
$arr2 = ['a'=>['b'=>['c'=>['h'=>['i'=>['j'=>'http://www.hihtml5.com/']]]]]];

echo '读取已存在的多维元素: ';
echo Node::get($arr1, 'a.b.c.d.e.f', '默认值'); // http://blog.csdn.net/zhouzme
echo '<hr>';

echo '读取不存在的多维元素: ';
echo Node::get($arr1, 'a.b.c.d.e.g', '默认值'); // 默认值
echo '<hr>';

echo '新增多维元素: ';
Node::set($arr1, 'a.b.c.d.e.g', 'http://www.ai9475.com/');
print_r($arr1);
echo '<hr>';

echo '读取新增的多维元素: ';
echo Node::get($arr1, 'a.b.c.d.e.g', '默认值'); // http://www.ai9475.com/
echo '<hr>';

echo '合并两个数组<br>';
Node::merge($arr1, $arr2);
print_r($arr1);

下面是对应的输出结果:

PHP多维数组元素操作类的方法

PHP多维数组元素操作类的方法

以上就是小编为大家带来的PHP多维数组元素操作类的方法全部内容了,希望大家多多支持三水点靠木~

PHP 相关文章推荐
PHP.MVC的模板标签系统(一)
Sep 05 PHP
WML,Apache,和 PHP 的介绍
Oct 09 PHP
PHP中设置时区方法小结
Jun 03 PHP
使用PHP实现阻止用户上传成人照片或者裸照
Dec 25 PHP
制作安全性高的PHP网站的几个实用要点
Dec 30 PHP
PHP+Apache+Mysql环境搭建教程
Aug 01 PHP
PHP使用PDO访问oracle数据库的步骤详解
Sep 29 PHP
PHP开发之用微信远程遥控服务器
Jan 25 PHP
PHP设计模式之委托模式定义与用法简单示例
Aug 13 PHP
PHP自定义错误处理的方法分析
Dec 19 PHP
关于Laravel参数验证的一些疑与惑
Nov 19 PHP
PHP设计模式之迭代器模式Iterator实例分析【对象行为型】
Apr 26 PHP
浅谈PHP中关于foreach使用引用变量的坑
Nov 14 #PHP
利用switch语句进行多选一判断的实例代码
Nov 14 #PHP
PHP表单验证内容是否为空的实现代码
Nov 14 #PHP
PHP环境搭建(php+Apache+mysql)
Nov 14 #PHP
10个值得深思的PHP面试题
Nov 14 #PHP
PHP生成word文档的三种实现方式
Nov 14 #PHP
php版微信返回用户text输入的方法
Nov 14 #PHP
You might like
ThinkPHP写数组插入与获取最新插入数据ID实例
2014/11/03 PHP
php将远程图片保存到本地服务器的实现代码
2015/08/03 PHP
php实现PDO中捕获SQL语句错误的方法
2017/02/16 PHP
PHP实现非阻塞模式的方法分析
2018/07/26 PHP
php使用array_chunk函数将一个数组分割成多个数组
2018/12/05 PHP
PHP执行系统命令函数实例讲解
2021/03/03 PHP
XHTML下,JS浮动代码失效的问题
2009/11/12 Javascript
JavaScript中Number.MIN_VALUE属性的使用示例
2015/06/04 Javascript
js实现图片旋转 js滚动鼠标中间对图片放大缩小
2017/07/05 Javascript
Angularjs添加排序查询功能的实例代码
2017/10/24 Javascript
vue使用中的内存泄漏【推荐】
2018/07/10 Javascript
JS判断用户用的哪个浏览器实例详解
2018/10/09 Javascript
axios实现文件上传并获取进度
2020/03/25 Javascript
js+canvas实现两张图片合并成一张图片的方法
2019/11/01 Javascript
javascript实现简单搜索功能
2020/03/26 Javascript
基于javascript实现日历功能原理及代码实例
2020/05/07 Javascript
[07:52]2014DOTA2 TI逗比武士游V社解说背后的故事
2014/07/10 DOTA
wxPython定时器wx.Timer简单应用实例
2015/06/03 Python
Python实现图片滑动式验证识别方法
2017/11/09 Python
Python 打印中文字符的三种方法
2018/08/14 Python
Python 实现加密过的PDF文件转WORD格式
2020/02/04 Python
python matplotlib.pyplot.plot()参数用法
2020/04/14 Python
python mock测试的示例
2020/10/19 Python
Python使用pyenv实现多环境管理
2021/02/05 Python
BAILEY 44官网:美国制造的女性服装
2019/07/01 全球购物
eBay比利时购物网站:eBay.be
2019/08/09 全球购物
回馈慈善的设计师太阳镜:DIFF eyewear
2019/10/17 全球购物
大学生两会学习心得体会
2014/03/10 职场文书
学校宣传标语
2014/06/18 职场文书
2015年挂职锻炼工作总结
2014/12/12 职场文书
2015年惩防体系建设工作总结
2015/05/22 职场文书
主持人大赛开场白
2015/05/29 职场文书
2015年城乡环境综合治理工作总结
2015/07/24 职场文书
小学四年级班务总结该怎么写?
2019/08/16 职场文书
前端学习——JavaScript原生实现购物车案例
2021/03/31 Javascript
muduo TcpServer模块源码分析
2022/04/26 Redis