php底层原理之变量(二)
上周我们从底层的角度介绍了php变量从生成->常量赋值->销毁的完整生命周期(不了解的同学可以翻看一下前面的文章),但是我们留了一个思考,不知道大家有答案了没,变量之间的赋值在底层又是如何实现的呢? 变量之间赋值php变量的zval结构,我们已经介绍了很多遍了,这里我们就不再多作介绍了。但是对于zval结构体中的 写时复制原理举例:
结果:
看到这里,大家可能会比较蒙。不是变量赋值了么?应该发生值拷贝了呀?怎么两个变量的引用计数不是1,而是2呢? 那是因为,php在设计的时候,为了节省内存,所以在变量之间赋值时,对于值相同的两个变量,会共用一块内存,也就是会在全局符号表内将变量b的变量指针指向变量a指向的同一个zval结构体,而只有当变量的zval结构发生变化时,才会发生变量容器复制的内存变化,也因此叫做 那什么时候会发生
举例:
结果:
写时改变原理变量之间的赋值我们搞清楚了,那么变量和引用之间的赋值呢?我们还是通过举例来说明 举例:
此时,我们发现,变量a和b的refcount还是2,只不过is_ref变成了1,那是因为在将变量a引用赋值给变量b时,在原变量容器上作了修改,将is_ref变成了1,且refcount+1 那如果引用赋值的基础上又发生了变量的改变了呢? 举例:
是不是觉得很神奇?变量b和变量a的值一起发生改变了~其实这是因为触发了
那么如果把刚刚举得几个例子合并在一起呢?最后结果又是什么呢? 举例:
结果:
整体执行过程是这样的,当执行到第二行时,变量容器的refcount会变成2,变量a和变量b共享同一个变量容器;当执行到第三行时,因为将变量a的引用赋值给变量c,但是变量b和变量a已经共享了同一个变量容器,此时变量容器如果要发生改变,因为refcount>2,所以会发生写时复制,将变量a和变量b分离,之后将变量a引用赋值给变量c时,则会原基础上进行修改,is_ref变成1,且refcount变成2 思考那么,下面的这个例子,最终结果是什么呢?欢迎大家在下方留言或私信我~ 举例:
如果你喜欢我的文章,请点赞支持我下,并欢迎关注我的专栏,每周都会有原创且有深度的文章奉上哟~ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |