php引用传参-php函数引用传参数组:functionset(array&$array,$path,$value)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了php引用传参-php函数引用传参数组:functionset(array&$array,$path,$value),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3773字,纯文字阅读大概需要6分钟。
内容图文
![php引用传参-php函数引用传参数组:functionset(array&$array,$path,$value)](/upload/InfoBanner/zyjiaocheng/238/7ca85480875a4a279fb3a727f7d88003.jpg)
function set(array &$array, $path, $value)
{
print_r($array);
echo('
');
$segments = explode('.', $path);
while(count($segments) > 1)
{
$segment = array_shift($segments);
if(!isset($array[$segment]) || !is_array($array[$segment]))
{
$array[$segment] = [];
}
$array =& $array[$segment];
print_r($array);
echo('
');
}
$array[array_shift($segments)] = $value;
print_r($array);
echo('
');
}
$arr = ['a' => 1, 'b' => 2, 'c' => 3];
set($arr, 'a.b.d', 4);
print_r($arr);
结果:
Array ( [a] => 1 [b] => 2 [c] => 3 )
Array ( )
Array ( )
Array ( [d] => 4 )
Array ( [a] => Array ( [b] => Array ( [d] => 4 ) ) [b] => 2 [c] => 3 )
为什么最终结果不是Array ( [d] => 4 ),而是 Array ( [a] => Array ( [b] => Array ( [d] => 4 ) ) [b] => 2 [c] => 3 ) ?
这个怎么解: $array =& $array[$segment];
回复内容:
function set(array &$array, $path, $value)
{
print_r($array);
echo('
');
$segments = explode('.', $path);
while(count($segments) > 1)
{
$segment = array_shift($segments);
if(!isset($array[$segment]) || !is_array($array[$segment]))
{
$array[$segment] = [];
}
$array =& $array[$segment];
print_r($array);
echo('
');
}
$array[array_shift($segments)] = $value;
print_r($array);
echo('
');
}
$arr = ['a' => 1, 'b' => 2, 'c' => 3];
set($arr, 'a.b.d', 4);
print_r($arr);
结果:
Array ( [a] => 1 [b] => 2 [c] => 3 )
Array ( )
Array ( )
Array ( [d] => 4 )
Array ( [a] => Array ( [b] => Array ( [d] => 4 ) ) [b] => 2 [c] => 3 )
为什么最终结果不是Array ( [d] => 4 ),而是 Array ( [a] => Array ( [b] => Array ( [d] => 4 ) ) [b] => 2 [c] => 3 ) ?
这个怎么解: $array =& $array[$segment];
首先,如果语句$array =& $array[$segment]
中的&
符号去掉,结果就如楼主所期待的最后输出Array([d] => 4)
。显然问题的关键就在那一句的&
上面。
我们知道php
在存储变量和变量的值时分别用了两种数据结构zval
和zval_value
。在zval
中包含四个字段:refcount_gc
表示引用计数is_ref_gc
表示是否为引用value
存储变量标识符type
变量的具体类型
变量的实际值存储在另一个联合体中,具体结构省略。现在我们来模拟一下过程:
首先$arr = ['a' => 1, 'b' => 2,'c' => 3]
创建:arr{'refcount_gc':1, 'is_ref_gc':0,'value':'arr','type':array}
(后面将会省略value和type的书写),同时创建array类型的zval_value。['a']{'refcount_gc':1, 'is_ref_gc':0, ...}
['b']{'refcount_gc':1, 'is_ref_gc':0, ...}
['c']{'refcount_gc':1, 'is_ref_gc':0, ...}
在调用set
方法时,传递的是$arr
的一个引用:&arr{'refcount_gc':2, 'is_ref_gc':1, ...}
接着进入函数体,while
循环内,第一次由于!is_array($arr['a'])
成立,为$arr['a']
赋值空数组。['a']{'refcount_gc':1, 'is_ref_gc':0, ...}
,并创建类型为array的zval_value。$arr =& $arr['a'];
这一句又将原数组的['a']
转为引用['a']:{'refcount_gc':2, 'is_ref_gc':1, ...}
,它和arr
都同时是这个空数组的引用①。
接着第二次循环,由于此时arr是一个空数组的引用,!isset($arr['b'])
成立,为$arr['b']
赋值空数组。arr['b']{'refcount_gc':2, 'is_ref_gc':1, ...}
,并创建类型为array的zval_value,同时由于①,原来数组的['a']
也是这个空数组的引用, 也就是在原数组['a']
基础上有了['a']['b']
②。$arr =& $arr['b'];
这一句又将arr['b']
转为引用arr['b']:{'refcount_gc':3, 'is_ref_gc':1, ...}
,由于②,①中的空数组的['b']
,原数组的['a']['b']
和arr都同时是这个空数组的引用③。
然后退出循环。$arr['d'] = 4;
为②中的空数组创建索引['d']
,且由于③,原数组的['a']['b']
、①中数组的['b']
也是这个数组的引用,他们都指向了这个(['d'] => 4)
的数组。
所以最后打印原数组出来的就是Array ( [a] => Array ( [b] => Array ( [d] => 4 ) ) [b] => 2 [c] => 3 )
简化的图示为:
画的比较随意。。大致按数字步骤体现其过程。。。
问题主要出现在
while(count($segments) > 1)
{
$segment = array_shift($segments);
if(!isset($array[$segment]) || !is_array($array[$segment]))
{
$array[$segment] = [];
}
//这里传引用赋值,将$array[$segment]的引用传给了$array
//所以此后的$array已经不再指向传参近来的那个$array(但传参进来的那个$array并未消失)
//最简单的方法是将这个&去掉,在
输出一遍,你应该就明白了
$array =& $array[$segment];
print_r($array);
echo(''); }
运行一下,如果不明白有问题可以留言
内容总结
以上是互联网集市为您收集整理的php引用传参-php函数引用传参数组:functionset(array&$array,$path,$value)全部内容,希望文章能够帮你解决php引用传参-php函数引用传参数组:functionset(array&$array,$path,$value)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。