PHP多维数组eval与循环实现以及效率(真实测试过,研究了半天后来才找到的资料,对组合报表很有用)

PHP多维数组eval与循环实现以及效率

框架里有个获取多维数组配置参数 赋值和取值 的功能,之前是简单的使用 eval 实现的,但感觉使用 eval 是不太好的办法,一直想用其他办法取代

1. eval 的安全问题,2 性能问题,3 服务器\空间兼容性问题 禁用 eval

前段时间测试了下 循环来实现,但没有成功,今天重写功能,终于实现了多维数组自动赋值与取值功能,不需要使用递归

环境:PHP5.4.7,以下展示代码是从我测试代码中提取出来,只展示主要实现,如要自己测试还需要重新整理下

数据,示例已存在的一组数组:

1
2
3
4
5
6
7
8
$c [ 'a' ][ 'a1' ][ 'a2' ][ 'a3' ][ 'a4' ][ 'a5' ] = 'a' ;
$c [ 'a' ][ 'a1' ][ 'a2' ][ 'a3' ][ 'a4' ][ 'a6' ] = 'a' ;
$c [ 'b' ][ 'b1' ][ 'b2' ][ 'b3' ][ 'b4' ][ 'b5' ] = 'b' ;
$c [ 'b' ][ 'b1' ][ 'b2' ][ 'b3' ][ 'b4' ][ 'b6' ] = 'b' ;
$c [ 'c' ][ 'c1' ][ 'c2' ][ 'c3' ][ 'c4' ][ 'c5' ] = 'c' ;
$c [ 'c' ][ 'c1' ][ 'c2' ][ 'c3' ][ 'c4' ][ 'c6' ] = 'c' ;
$c [ 'd' ][ 'd1' ][ 'd2' ][ 'd3' ][ 'd4' ][ 'd5' ] = 'd' ;
$c [ 'e' ][ 'e1' ][ 'e2' ][ 'e3' ][ 'e4' ][ 'e6' ] = 'e' ;

指定取值\赋值节点:

1
$key = 'a.a1.a2.a3.a4.a5' ;

一、多维数组赋值:

1. 简单方法使用 eval

1
eval ( '$c[\'' . str_replace ( '.' , '\'][\'' , $key ) . '\'] = $value;' );

2. 使用循环赋值

1
2
3
4
5
6
7
8
9
10
11
12
$nodes = explode ( '.' , $key );
$config = & $c ;
foreach ( $nodes as $node ) {
    if (isset( $config [ $node ])) {
        $config = & $config [ $node ];
    }
    else {
        $config [ $node ] = array ();
        $config = & $config [ $node ];
    }
}
$config = $value ;

二、多数组取值:

1. 简单方法使用 eval,(实际部署还应该加入 isset 判断后取值才行)

1
eval ( '$value = $c[\'' . str_replace ( '.' , '\'][\'' , $key ) . '\'];' );

2. 使用循环取值

1
2
3
4
5
6
7
8
9
10
11
$value = $config ;
$nodes = explode ( '.' , $key );
foreach ( $nodes as $node ) {
    if (isset( $value [ $node ])) {
        $value = $value [ $node ];
    }
    else {
        $value = null;
        break ;
    }
}

针对 PHP5.4 的取值应该还有一种简便的方法:

1
2
3
4
5
6
7
function g() {
    global $c ;
    return $c ;
}
echo '<pre>' ;
$a = g()[ 'a' ][ 'a1' ][ 'a2' ][ 'a3' ][ 'a4' ];
print_r( $a );

也许感觉起来还是有些复杂吧,特别是当某一维度元素不存在时无法判断

以上代码的应用方式可简单封装为:

1
2
3
4
5
set( $nodes , $value );
set( 'a.a1.a2.a3.a4.a5' , 'test' );
      
get( $nodes );
get( 'a.a1.a2.a3.a4.a5' );

这样再深的维度也不怕

---------------------------------------------------------------------------------------

大概实现过程就是这样,已经过多种方式测试没有问题,下面说下测试的性能:

过程没什么可多说的,直说结果了:

---------------------------------------------------------------------------------------

1000000 一百万次循环的比较:

赋值 速度:

eval 用时:36秒

循环用时 :17秒

相差至少两倍;

取值速度:

eval用时:33秒

循环用时:7秒

相差近5倍左右

维度加深测试:

循环 和 eval 差别不大,

维度6级增加到13级时平均每加深一级,赋值耗时增加约 0.7秒,取值增加 0.3秒

----------------------------------------------------------------------------------------

其他提示:

  1. 首先总体性能跟数组体积有关这是肯定的;

  2. 数组维数深度对性能的影响不是特别大,我上面测试使用的是13维深度,普通应用基本上都在4维以下吧,所以深度问题带来的性能问题几乎可以忽略。

  3. 另外根据我之前看到的一些文章总结推荐使用多维数组而不是分散的数组存储数组,有效利用内存,总体性能也许更好;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值