V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  noark9  ›  全部回复第 3 页 / 共 8 页
回复总数  156
1  2  3  4  5  6  7  8  
2017 年 5 月 11 日
回复了 543400 创建的主题 PHP 我又来了,关于函数数组里面怎么创建新的键值问题
@543400
最近刚好在研究 PHP 内存管理方面的问题,但是如果是 C 就好了,可以很容易把内存地址打印出来,PHP 没有这么个东西来做,但是 PHP 提供了查看变量内存引用计数的函数 debug_zval_dump,配合你的代码做下分析

// 上半部分代码不变
function demoArray(){

return array(
"a"=>"我是 a",
"b"=>"我是 b",

);

};
// 把你代码下面改一下改成这样
echo "\nS.1 -----------------------\n";
debug_zval_dump(demoArray());
unset( demoArray()["a"] );
debug_zval_dump(demoArray());

echo "\nS.2 -----------------------\n";
$aa=demoArray();
debug_zval_dump(demoArray());
debug_zval_dump($aa);

echo "\nS.3 -----------------------\n";
unset($aa['a']);
debug_zval_dump(demoArray());
debug_zval_dump($aa);

对应下面的输出,下面来细说具体,下面的 refcount 就是引用数量,代表有多少个变量引用着这个变量,但是要注意的是 debug_zval_dump 函数自身会对变量产生一个引用,也就是真实的引用数量实际上是下面的数字 -1,如果 refcount - 1 = 0 了说明上下文代码中没有引用到这个变量,在 debug_zval_dump 调用结束后,他的内存就会被回收

S.1 -----------------------
代码是这样

echo "\nS.1 -----------------------\n";
debug_zval_dump(demoArray());
unset( demoArray()["a"] );
debug_zval_dump(demoArray());

输出是这样
array(2) refcount(1){
["a"]=>
string(8) "我是 a" refcount(2)
["b"]=>
string(8) "我是 b" refcount(2)
}
array(2) refcount(1){
["a"]=>
string(8) "我是 a" refcount(2)
["b"]=>
string(8) "我是 b" refcount(2)
}
这里,是用来比较 unset 对 demoArray() 的影响
可以看到 unset(demoArray()['a']) 对 demoArray() 函数的返回值没有任何的影响
也说明了每次 demoArray() 返回的结果是相互独立的
其中对于数组的 refcount = 1 是 debug_zval_dump 函数产生的,对于数组中两个元素的 refcount = 2 是数组本身对数组中变量的引用和 debug_zval_dump 函数对数组两个元素的引用

S.2 -----------------------
代码是这样

echo "\nS.2 -----------------------\n";
$aa=demoArray();
debug_zval_dump(demoArray());
debug_zval_dump($aa);

输出是这样

array(2) refcount(1){
["a"]=>
string(8) "我是 a" refcount(3)
["b"]=>
string(8) "我是 b" refcount(3)
}
array(2) refcount(2){
["a"]=>
string(8) "我是 a" refcount(2)
["b"]=>
string(8) "我是 b" refcount(2)
}
这里是看使用 $aa = demoArray() 对引用计数的影响
第一组结果:数组的引用数量还是 1 证明只有 debug_zval_dump 函数对其引用了,但是里面的数组元素的引用数变成了 3 这是因为除了第一步中说到的 debug_zval_dump() 函数,和 demoArray() 返回的数组本身对这两个元素进行了引用,还有赋值以后 $aa 这个数组,对这两个元素进行了引用( PHP 是写时复制,也就是说,在不改变变量的情况下,PHP 并不会真实的复制变量,而是对原来变量的引用计数 +1,等到真实的发生读写的时候,才会创建新的变量)
第二组结果:对于数组本身,那就是 $aa 这个变量和 debug_zval_dump 函数对其引用,所以数组的引用数是 2,但是为什么元素的引用数是 1 呢?之前直接 debug_zval_dump 输出的为什么会更多呢?因为 debug_zval_dump 输出后,没有变量接收 debug_zval_dump(demoArray()); 这里 demoArray() 的返回值(没有变量引用 debug_zval_dump 函数里面 demoArray() 调用的结果)所以,这里引用计数变成 2,也就是数组 $aa 和 debug_zval_dump 分别对数组和数组里面的元素进行引用

S.3 -----------------------
代码是这样

echo "\nS.3 -----------------------\n";
unset($aa['a']);
debug_zval_dump(demoArray());
debug_zval_dump($aa);

输出是这样

array(2) refcount(1){
["a"]=>
string(8) "我是 a" refcount(2)
["b"]=>
string(8) "我是 b" refcount(3)
}
array(1) refcount(2){
["b"]=>
string(8) "我是 b" refcount(2)
}
这里是看 unset($aa['a']) 对引用计数的影响
在进行了 unset($aa['a']) 之后
第一组数据,直接输出 debug_zval_dump(demoArray()); 的结果,和 S2 中接近,但是数组中 a 元素的引用变成了 2,也就是说明 unset 有效果了,引用数组中的 a 元素的变量少了一个
第二组数据也就是 $aa 的引用情况,和预想的相同,a 没了,b 不变

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

总结---------------------------------------

1. 上面三组输出,每一组 debug_zval_dump(demoArray()); 的输出结果都是一样的,可以侧面证明,每次 demoArray() 返回的数组,实际上都是独立的一个数组
2. 使用 $aa 变量存储了 demoArray() 返回的数组后,debug_zval_dump(demoArray()); 数组的引用计数器并未增加,证明 $aa 保存的数组和 demoArray() 返回的数组并没有关系
但是数组中元素的引用计数器变化证明,使用 $aa 存储了 demoArray() 返回的数组后,可以认为 $aa 保存数组的元素
3. 使用 unset($aa['a']) 后,数组中元素引用计数器变化,也证明了在这个时候 $aa 和 demoArray() 返回的数组是没关系的

撒花完结~~~~~~

补充下,我不是大神,大家一起交流学习才能提高,因为近期在写 php 的项目,很多经验是在使用其他语言开发的时候带过来的,但是基础概念是相通的,你说的那个参考文档没看过,因为在我用过的语言没有遇到过需要先使用临时变量获取函数结果(当然你说了我懒得去查这是个什么概念是我的锅),再使用结果的情况(我从 PHP 5.6 开始使用,去年升级公司服务器到 PHP7 就更没接触过了),这里涉及到了内存管理的一些知识,如果是 C 可以不用这么复杂的解释,直接打印内存地址就可以了
2017 年 5 月 11 日
回复了 543400 创建的主题 PHP 我又来了,关于函数数组里面怎么创建新的键值问题
我说的是把 unset($aa['a']) 放到 $aa = demoArray() 下面
另外 demoArray() 函数每次返回确实都是一个独立的数组对象,所以你使用 unset(demoArray()['a']) 是没用的

unset(demoArray()['a']); 这行代码,本质上你可以认为解释器做了下面的操作

$tmp = demoArray();
unset($tmp);

---------------分割线,也就是说你的程序本质上变成下面的样子
function demoArray(){

return array(
"a"=>"我是 a",
"b"=>"我是 b",

);

};


$tmp = demoArray(); // 这里原来是这样的 unset( demoArray()["a"] );
unset($tmp);

$aa=demoArray();
echo $aa["a"];
---------------分割线

所以我说你 unset(demoArray()['a']) 和下面 $aa = demoArray(); 所操作的是两个独立的数组

你所说的间接引用数组,看了你发的文档才知道-,-原来以前的 php 这么二,函数返回值必须要用临时变量保存,不能直接使用,你那中文文档我没见过,这么翻译也很诡异

其次,不用说打脸不打脸,台阶不台阶,大家讨论问题,淡定点
2017 年 5 月 11 日
回复了 hellowego 创建的主题 问与答 充电电源是伪命题吗
好东西啊,租回来,里面放个小电脑,手机一插,所有艳照就都同步过去了,过几天再去回收艳照和电话号码
2017 年 5 月 11 日
回复了 543400 创建的主题 PHP 我又来了,关于函数数组里面怎么创建新的键值问题
你代码里面,每次 demoArray() 实际上是创建了一个新的数组出来,也就是你 unset(demoArray()['a ‘]) 和下面 echo $aa['a'] 是两个东西
你把 unset 放在 $aa = demoArray() 后面,就有效了
上一个问题也没有拒绝回答,你说不输出,那么你原来代码用的是 = 不是语法有错么,原文问题没有提到 unset 的问题嘛,后面才加的
以及,问题,什么是间接调用数组,没明白这个话,从你代码上看,就是一个函数返回了一个数组
2017 年 5 月 9 日
回复了 543400 创建的主题 PHP 我又来了,关于函数数组里面怎么创建新的键值问题
每次调用 demoArray 方法都会返回一个独立的数组对象,那你这里 unset( demoArray()["a"] ); 做 unset 跟下面 $aa=demoArray(); 所获取到的数组对象半毛钱关系都没有啊
以及你的问题很不清晰,“间接调用数组的方式做出详细创建数组的方法” 是什么意思
2017 年 5 月 8 日
回复了 543400 创建的主题 PHP 我又来了,关于函数数组里面怎么创建新的键值问题
return array(
"a"=>"我是 a",
"b"=>"我是 b",

);

不是应该这样?难道 run 的时候没提示语法错误?
2017 年 5 月 6 日
回复了 Ouyangan 创建的主题 JavaScript 写前端是真的累
跟用户对接的地方,要考虑各种各样奇奇怪怪的现象 + 实现各种各样奇奇怪怪的 UI,虽然有的 UI 看上去没那么奇怪
2017 年 5 月 1 日
回复了 thekoc 创建的主题 macOS QQ Mac 版搜索聊天记录功能有问题?
MacQQ 一直各种问题。。。比如聊天记录随时会不见。。。
2017 年 4 月 15 日
回复了 kwutcc 创建的主题 职场话题 被同事问到薪资该怎么回答呢
不管交际如何的同事从来没有说过工资多少
2017 年 4 月 5 日
回复了 acthtml 创建的主题 问与答 有没有 sublime/vscode 的微信分享插件?
WakaTime 截图分享
没被吓到。。。
2017 年 3 月 13 日
回复了 artandlol 创建的主题 Linux 发现处理十万条以上数据的时候 sed、awk 命令就 bug 了
从未遇到过,你确定你的数据只是按行还是有增加,或者数据没问题,之前导数据的时候三五百万是松松的处理啊
曾经 xcode 的重构把代码各种改坏,或者直接重构的时候就卡死,所以再也不用
2017 年 2 月 17 日
回复了 peng 创建的主题 iDev WWDC 2017 官宣 6.5 - 6.9 圣何塞
也不知道苹果爸爸啥时候能把 xcode 做稳?
2017 年 2 月 7 日
回复了 qq258076067 创建的主题 iOS 有偿求助 iOS 开发问题
好奇下楼主为什么要在 iOS 上 rewrite url ?是需要用 iPhone 做服务器么?
jq 入门好东西,感谢推荐啊,哈哈
2016 年 11 月 10 日
回复了 sea516 创建的主题 生活 假设一个情景,你有一天突然意外去世。你做好准备了吗?
大家不是应该觉得自己是天选之人没那么容易死么-,-
哈哈,这个好
2016 年 11 月 7 日
回复了 cilbup 创建的主题 iDev 求推荐类似 C-Free 的 C/C++编程开发工具
CodeRunner 很好用啊
1  2  3  4  5  6  7  8  
关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   3963 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 147ms · UTC 00:57 · PVG 08:57 · LAX 16:57 · JFK 19:57
♥ Do have faith in what you're doing.