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 读取shell管道传输过来的内容
Mar 01 PHP
使用PHP 5.0创建图形的巧妙方法
Oct 12 PHP
在WAMP环境下搭建ZendDebugger php调试工具的方法
Jul 18 PHP
基于PHP中的常用函数回顾
Jul 11 PHP
php实现按文件名搜索文件的远程文件查找器
May 10 PHP
thinkphp中ajax与php响应过程详解
Dec 08 PHP
php自定义错误处理用法实例
Mar 20 PHP
PHP实现生成带背景的图形验证码功能
Oct 03 PHP
在Thinkphp中使用ajax实现无刷新分页的方法
Oct 25 PHP
php 解决扫描二维码下载跳转问题
Jan 13 PHP
PHP使用PDO操作sqlite数据库应用案例
Mar 07 PHP
php使用event扩展的io复用测试的示例
Oct 20 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
PHP中用header图片地址 简单隐藏图片源地址
2008/04/09 PHP
用mysql_fetch_array()获取当前行数据的方法详解
2013/06/05 PHP
Thinkphp整合阿里云OSS图片上传实例代码
2019/04/28 PHP
laravel框架创建授权策略实例分析
2019/11/22 PHP
PHP7 其他修改
2021/03/09 PHP
javascript div 遮罩层封锁整个页面
2009/07/10 Javascript
js将字符串转成正则表达式的实现方法
2013/11/13 Javascript
我的Node.js学习之路(四)--单元测试
2014/07/06 Javascript
javascript中2个感叹号的用法实例详解
2014/09/04 Javascript
jQuery随机密码生成的方法
2015/03/09 Javascript
JS获取下拉框显示值和判断单选按钮的方法
2015/07/09 Javascript
微信小程序 MD5加密登录密码详解及实例代码
2017/01/12 Javascript
JavaScript中使用Async实现异步控制
2017/08/15 Javascript
vue项目中使用axios上传图片等文件操作
2017/11/02 Javascript
JS数组扁平化(flat)方法总结详解
2019/06/24 Javascript
Vue实现点击当前元素以外的地方隐藏当前元素(实现思路)
2019/12/04 Javascript
ReactRouter的实现方法
2021/01/25 Javascript
[46:25]DOTA2上海特级锦标赛主赛事日 - 4 败者组第五轮 MVP.Phx VS EG第二局
2016/03/05 DOTA
[46:23]OG vs EG 2018国际邀请赛淘汰赛BO3 第一场 8.23
2018/08/24 DOTA
[51:17]Mineski vs Secret 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.22
2019/09/05 DOTA
Python遍历目录的4种方法实例介绍
2015/04/13 Python
Python 实现文件的全备份和差异备份详解
2016/12/27 Python
Python爬虫DNS解析缓存方法实例分析
2017/06/02 Python
python3+PyQt5实现自定义窗口部件Counters
2018/04/20 Python
Python批处理更改文件名os.rename的方法
2018/10/26 Python
numpy 计算两个数组重复程度的方法
2018/11/07 Python
动态设置django的model field的默认值操作步骤
2020/03/30 Python
菲律宾领先的在线时尚商店:Zalora菲律宾
2018/02/08 全球购物
创业计划书六个要素
2013/12/26 职场文书
四年级科学教学反思
2014/02/10 职场文书
趣味比赛活动方案
2014/02/15 职场文书
高三毕业寄语
2014/04/10 职场文书
纪检干部对照检查材料
2014/08/22 职场文书
支部书记四风问题自我剖析材料
2014/09/29 职场文书
运动会跳远广播稿
2015/08/19 职场文书
阿里云服务器Ubuntu 20.04上安装Odoo 15
2022/05/20 Servers