PHP 变量分析详解

php中的变量的使用可以说的上是所有编程中最简单的了,但是您真的理解变量的底层机制吗?
不用担心看完这篇文章您就懂啦~

关于COW 机制(copy on write,写时复制,一种内存优化机制)
$a=range(0,10000);
var_dump(memory_get_usage());
$b=$a;
var_dump(memory_get_usage());//因为COW 机制,此时并不会为变量b单独开辟内存空间
$a=range(0,10000);
var_dump(memory_get_usage());//由于$a被重新赋值,所以会重新开辟内存空间

运行结果:
int(769600)
int(769632) //和上面结果不同是因为多了变量名b
int(1166992)//由于对变量a进行写操作(值不变),所以会copy一份a变量空间

引用变量

php中的引用变量比较简单,“引用” 我觉得可以理解成别名吧,比如某人叫“张三”,绰号“阿三”,其实都指的是一个人。
也就是说,php的变量引用操作的任然是原变量;

$a=range(0,5);
print_r($a);
$b=&$a;
$b=range('a','f');
print_r($a);
print_r($b);

运行结果:
Array
(
    [0] => 0
    [1] => 1
    [2] => 2
    [3] => 3
    [4] => 4
    [5] => 5
)
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
    [4] => e
    [5] => f
)
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
    [4] => e
    [5] => f
)

在php中,每个php变量存在一个叫"zval"的变量容器中,可以通过xdebug可以分析变量分布情况。
在代码中使用xdebug_debug_zval查看变量时发现refcount会按照赋值类型进行计数:
(花了点时间分析,认可的话点个赞呗~)

定义一个变量后,默认情况:refcount=1,is_ref=0;
1.如果该变量未被引用过,则is_ref=0, refcount=1+变量赋值的次数
2.若该变量被引用过,则is_ref=1 , refcount=1+引用的次数

$a=range(0,5);
xdebug_debug_zval('a');//只有a变量在使用这个变量容器,so, refcount=1, is_ref=0
$b=$a;//把一个变量赋值给另一变量将增加引用次数(refcount).
$c=&$a;
$d=&$a;
$e=$a;
$f=$a;
$g=$a;
xdebug_debug_zval('a');//因为a被引用赋值过,所以is_ref=1,refcount只会统计引用赋值的个数(refcount=refcount+2)
//下面可以把上面的引用$c=&$a;$d=&$a;删掉然后依然查看a变量xdebug_debug_zval('a');结果一样,此处是为了运行效果
xdebug_debug_zval('e');//因为e未被引用赋值过,所以is_ref=0,refcount会统计直接赋值的个数(refcount=refcount+4)

运行结果:
a:
(refcount=1, is_ref=0)// 默认情况下
array (size=6)
  0 => (refcount=0, is_ref=0)int 0
  1 => (refcount=0, is_ref=0)int 1
  2 => (refcount=0, is_ref=0)int 2
  3 => (refcount=0, is_ref=0)int 3
  4 => (refcount=0, is_ref=0)int 4
  5 => (refcount=0, is_ref=0)int 5
a:
(refcount=3, is_ref=1)// 该变量容器被变量a , c , d指向
array (size=6)
  0 => (refcount=0, is_ref=0)int 0
  1 => (refcount=0, is_ref=0)int 1
  2 => (refcount=0, is_ref=0)int 2
  3 => (refcount=0, is_ref=0)int 3
  4 => (refcount=0, is_ref=0)int 4
  5 => (refcount=0, is_ref=0)int 5
e:
(refcount=5, is_ref=0)// 该变量容器被变量a , b , e , f , g指向
array (size=6)
  0 => (refcount=0, is_ref=0)int 0
  1 => (refcount=0, is_ref=0)int 1
  2 => (refcount=0, is_ref=0)int 2
  3 => (refcount=0, is_ref=0)int 3
  4 => (refcount=0, is_ref=0)int 4
  5 => (refcount=0, is_ref=0)int 5

unset

unset只会取消引用,不会销毁空间
下面的代码让你秒懂:

$a="hello";
$b=&$a;
unset($b);
echo $a;

运行结果:hello
//后面两行改成:
unset($a);
echo $b;
运行结果依然不变。

上面的运行结果显而易见了吧 _

对象

php中的对象本质就是引用,不用加符号&。

class Person{
    public $name="xiao ming";
}
$p1=new Person();
xdebug_debug_zval('p1');
$p2=$p1;//此处本质是引用,不是对象克隆,我测试,写成p2=&$p1也可以,本质都是引用赋值
$p2->name="xiao qiang";
xdebug_debug_zval('p1');

运行结果:
p1:
(refcount=1, is_ref=0)
object(Person)[1]
  public 'name' => (refcount=2, is_ref=0)string 'xiao ming' (length=9)
p1:
(refcount=2, is_ref=0)
object(Person)[1]
  public 'name' => (refcount=0, is_ref=0)string 'xiao qiang' (length=10)

既然p2是p1的引用,为啥 is_ref不等于1呢?
若写成写成p2=&$p1 ,is_ref是等于1的,这可能就是对象变量特殊性吧!
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343