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+MySQL的聊天室设计
Oct 09 PHP
php for 循环语句使用方法详细说明
May 09 PHP
php操作mysqli(示例代码)
Oct 28 PHP
PHP 字符串长度判断效率更高的方法
Mar 02 PHP
Yii 快速,安全,专业的PHP框架
Sep 03 PHP
PHP中file_exists使用中遇到的问题小结
Apr 05 PHP
thinkPHP5.0框架环境变量配置方法
Mar 17 PHP
PHP正则删除HTML代码中宽高样式的方法
Jun 12 PHP
PHP PDOStatement::execute讲解
Jan 31 PHP
PHP使用 Pear 进行安装和卸载包的方法详解
Jul 08 PHP
PHP正则之正向预查与反向预查讲解与实例
Apr 06 PHP
PHP设计模式之命令模式示例详解
Dec 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取进制余数函数代码
2012/01/19 PHP
PHP MSSQL 分页实例
2016/04/13 PHP
php 数组随机取值的简单实例
2016/05/23 PHP
php简单统计中文个数的方法
2016/09/30 PHP
PHP使用Redis长连接的方法详解
2018/02/12 PHP
PHP设计模式之原型模式定义与用法详解
2018/04/03 PHP
浅谈Laravel中的三种中间件的作用
2019/10/13 PHP
RGB颜色值转HTML十六进制(HEX)代码的JS函数
2009/04/25 Javascript
javascript实现上传图片并预览的效果实现代码
2011/04/11 Javascript
JavaScript与DOM组合动态创建表格实例
2012/12/23 Javascript
文本有关的样式和jQuery求对象的高宽问题分别说明
2013/08/30 Javascript
JS实现动态增加和删除li标签行的实例代码
2016/10/16 Javascript
Vue.js学习笔记之常用模板语法详解
2017/07/25 Javascript
vue 使用Jade模板写html,stylus写css的方法
2018/02/23 Javascript
基于mpvue的小程序项目搭建的步骤
2018/05/22 Javascript
JavaScript类数组对象转换为数组对象的方法实例分析
2018/07/24 Javascript
JavaScript中的this基本问题实例小结
2020/03/09 Javascript
vue 根据选择的月份动态展示日期对应的星期几
2021/02/06 Vue.js
基于Python的身份证号码自动生成程序
2014/08/15 Python
python通过openpyxl生成Excel文件的方法
2015/05/12 Python
python出现&quot;IndentationError: unexpected indent&quot;错误解决办法
2017/10/15 Python
python实现简易通讯录修改版
2018/03/13 Python
Django rest framework工具包简单用法示例
2018/07/20 Python
对Pyhon实现静态变量全局变量的方法详解
2019/01/11 Python
Django实现文章详情页面跳转代码实例
2020/09/16 Python
Django Model层F,Q对象和聚合函数原理解析
2020/11/12 Python
python实现图片转字符画
2021/02/19 Python
女士鞋子、包包和服装在线,第一款10美元:ShoeDazzle
2019/07/26 全球购物
荷兰网上药店:Drogisterij.net
2019/09/03 全球购物
机电专业大学生职业规划书范文
2014/02/25 职场文书
2014年五一活动策划方案
2014/03/15 职场文书
团代会主持词
2014/04/02 职场文书
数学系毕业生求职信
2014/05/29 职场文书
自书遗嘱范文
2015/08/07 职场文书
Java新手教程之ArrayList的基本使用
2021/06/20 Java/Android
Win11任务栏太宽了怎么办?一招解决Win11任务栏太宽问题
2021/11/21 数码科技