国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

php底層原理之變量(二)

bladefury / 3509人閱讀

摘要:但是對(duì)于結(jié)構(gòu)體中的和字段我們一直都沒(méi)有詳細(xì)介紹過(guò),而這兩個(gè)字段其實(shí)是和變量之間賦值的原理有著密切的關(guān)系的。

上周我們從底層的角度介紹了php變量從生成->常量賦值->銷(xiāo)毀的完整生命周期(不了解的同學(xué)可以翻看一下前面的文章php底層原理之變量(一)),但是我們留了一個(gè)思考,不知道大家有答案了沒(méi),變量之間的賦值在底層又是如何實(shí)現(xiàn)的呢?

變量之間賦值

php變量的zval結(jié)構(gòu),我們已經(jīng)介紹了很多遍了,這里我們就不再多作介紹了。但是對(duì)于zval結(jié)構(gòu)體中的refcount__gcis_ref__gc字段我們一直都沒(méi)有詳細(xì)介紹過(guò),而這兩個(gè)字段其實(shí)是和變量之間賦值的原理有著密切的關(guān)系的。所以,我們這次從幾個(gè)例子入手,了解這兩個(gè)字段的變化和由此帶來(lái)的原理知識(shí)

寫(xiě)時(shí)復(fù)制原理

舉例:

$a = "許錚的技術(shù)成長(zhǎng)之路";
$b = $a;
xdebug_debug_zval("a", "b");

結(jié)果:

a: (refcount=2, is_ref=0)="許錚的技術(shù)成長(zhǎng)之路"
b: (refcount=2, is_ref=0)="許錚的技術(shù)成長(zhǎng)之路"

看到這里,大家可能會(huì)比較蒙。不是變量賦值了么?應(yīng)該發(fā)生值拷貝了呀?怎么兩個(gè)變量的引用計(jì)數(shù)不是1,而是2呢?

那是因?yàn)椋?strong>php在設(shè)計(jì)的時(shí)候,為了節(jié)省內(nèi)存,所以在變量之間賦值時(shí),對(duì)于值相同的兩個(gè)變量,會(huì)共用一塊內(nèi)存,也就是會(huì)在全局符號(hào)表內(nèi)將變量b的變量指針指向變量a指向的同一個(gè)zval結(jié)構(gòu)體,而只有當(dāng)變量的zval結(jié)構(gòu)發(fā)生變化時(shí),才會(huì)發(fā)生變量容器復(fù)制的內(nèi)存變化,也因此叫做寫(xiě)時(shí)復(fù)制原理

那什么時(shí)候會(huì)發(fā)生寫(xiě)時(shí)復(fù)制原理呢?

寫(xiě)時(shí)復(fù)制原理觸發(fā)時(shí)機(jī):
php在修改一個(gè)變量時(shí),如果發(fā)現(xiàn)變量的refcount>1,則會(huì)執(zhí)行變量容器的內(nèi)存復(fù)制

舉例:

$a = "許錚的技術(shù)成長(zhǎng)之路";
$b = $a; //此時(shí)變量a和變量b共同指向同一個(gè)變量容器,即refcount>1
$b = "許錚的技術(shù)成長(zhǎng)之路1" //觸發(fā)寫(xiě)時(shí)復(fù)制機(jī)制
xdebug_debug_zval("a", "b");

結(jié)果:

a: (refcount=1, is_ref=0)="許錚的技術(shù)成長(zhǎng)之路"
b: (refcount=1, is_ref=0)="許錚的技術(shù)成長(zhǎng)之路1"
寫(xiě)時(shí)改變?cè)?/b>

變量之間的賦值我們搞清楚了,那么變量和引用之間的賦值呢?我們還是通過(guò)舉例來(lái)說(shuō)明

舉例:

$a = "許錚的技術(shù)成長(zhǎng)之路";
$b = &$a;
xdebug_debug_zval("a", "b");

結(jié)果:

a: (refcount=2, is_ref=1)="許錚的技術(shù)成長(zhǎng)之路"
b: (refcount=2, is_ref=1)="許錚的技術(shù)成長(zhǎng)之路"

此時(shí),我們發(fā)現(xiàn),變量a和b的refcount還是2,只不過(guò)is_ref變成了1,那是因?yàn)樵趯⒆兞縜引用賦值給變量b時(shí),在原變量容器上作了修改,將is_ref變成了1,且refcount+1

那如果引用賦值的基礎(chǔ)上又發(fā)生了變量的改變了呢?

舉例:

$a = "許錚的技術(shù)成長(zhǎng)之路";
$b = &$a;
$b = "許錚的技術(shù)成長(zhǎng)之路1"
xdebug_debug_zval("a", "b");

結(jié)果:

a: (refcount=2, is_ref=1)="許錚的技術(shù)成長(zhǎng)之路1"
b: (refcount=2, is_ref=1)="許錚的技術(shù)成長(zhǎng)之路1"

是不是覺(jué)得很神奇?變量b和變量a的值一起發(fā)生改變了~其實(shí)這是因?yàn)橛|發(fā)了寫(xiě)時(shí)改變?cè)?/b>

寫(xiě)時(shí)改變?cè)?/b>觸發(fā)時(shí)機(jī):
is_ref為1的變量容器在被賦值之前,優(yōu)先檢查變量容器的is_ref是否等于1,如果為1,則不進(jìn)行寫(xiě)時(shí)復(fù)制,而是在原變量容器基礎(chǔ)上作內(nèi)容修改;而如果將is_ref為1的變量容器賦值給其他變量時(shí),則會(huì)立即觸發(fā)寫(xiě)時(shí)復(fù)制

那么如果把剛剛舉得幾個(gè)例子合并在一起呢?最后結(jié)果又是什么呢?

舉例:

$a = "許錚的技術(shù)成長(zhǎng)之路";
$b = $a; 
$c = &$a;
xdebug_debug_zval("a", "b", "c");

結(jié)果:

a: (refcount=2, is_ref=1)="許錚的技術(shù)成長(zhǎng)之路"
b: (refcount=1, is_ref=0)="許錚的技術(shù)成長(zhǎng)之路"
c: (refcount=2, is_ref=1)="許錚的技術(shù)成長(zhǎng)之路"

整體執(zhí)行過(guò)程是這樣的,當(dāng)執(zhí)行到第二行時(shí),變量容器的refcount會(huì)變成2,變量a和變量b共享同一個(gè)變量容器;當(dāng)執(zhí)行到第三行時(shí),因?yàn)閷⒆兞縜的引用賦值給變量c,但是變量b和變量a已經(jīng)共享了同一個(gè)變量容器,此時(shí)變量容器如果要發(fā)生改變,因?yàn)閞efcount>2,所以會(huì)發(fā)生寫(xiě)時(shí)復(fù)制,將變量a和變量b分離,之后將變量a引用賦值給變量c時(shí),則會(huì)原基礎(chǔ)上進(jìn)行修改,is_ref變成1,且refcount變成2

思考

那么,下面的這個(gè)例子,最終結(jié)果是什么呢?歡迎大家在下方留言或私信我~

舉例:

$a = "許錚的技術(shù)成長(zhǎng)之路";
$b = $a; 
$c = &$a;
$d = $a;
$e = "許錚的技術(shù)成長(zhǎng)之路1"
$a = $e;
xdebug_debug_zval("a", "b", "c", "d", "e");

如果你喜歡我的文章,請(qǐng)點(diǎn)贊支持我下,并歡迎關(guān)注我的專(zhuān)欄,每周都會(huì)有原創(chuàng)且有深度的文章奉上喲~

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/31087.html

相關(guān)文章

  • php底層原理數(shù)組實(shí)現(xiàn)

    摘要:數(shù)組是最常用的數(shù)據(jù)類(lèi)型,同時(shí)容易上手也得益于其強(qiáng)大的數(shù)組,但是數(shù)組在中是如何實(shí)現(xiàn)的呢首先,我們還是先了解下相關(guān)的數(shù)據(jù)結(jié)構(gòu),為下面的內(nèi)容打好基礎(chǔ)哈希表哈希表,顧名思義,即將不同的關(guān)鍵字映射到不同單元的一種數(shù)據(jù)結(jié)構(gòu)。 數(shù)組是PHPer最常用的數(shù)據(jù)類(lèi)型,同時(shí)php容易上手也得益于其強(qiáng)大的數(shù)組,但是數(shù)組在php中是如何實(shí)現(xiàn)的呢? 首先,我們還是先了解下相關(guān)的數(shù)據(jù)結(jié)構(gòu),為下面的內(nèi)容打好基礎(chǔ) 哈希...

    HackerShell 評(píng)論0 收藏0
  • php底層原理變量(一)

    摘要:對(duì)于來(lái)說(shuō),變量有全局變量和局部變量之分那么,他們都是存儲(chǔ)到一個(gè)哈希表內(nèi)了么其實(shí)不是的,變量存儲(chǔ)也有作用域的概念。 上次跟大家講了垃圾回收機(jī)制后,有些小伙伴對(duì)底層原理比較感興趣,私信問(wèn)我了一些關(guān)于變量的相關(guān)知識(shí),既然大家對(duì)變量比較感興趣,那么這次我們來(lái)系統(tǒng)的講一下變量的底層原理 變量結(jié)構(gòu) 首先,我們還是先擺上我們的zval結(jié)構(gòu)體,即php所有變量都會(huì)以zval結(jié)構(gòu)體的形式實(shí)現(xiàn) struc...

    curlyCheng 評(píng)論0 收藏0
  • php底層原理垃圾回收機(jī)制

    摘要:總結(jié)垃圾回收機(jī)制以的引用計(jì)數(shù)機(jī)制為基礎(chǔ)以前只有該機(jī)制同時(shí)使用根緩沖區(qū)機(jī)制,當(dāng)發(fā)現(xiàn)有存在循環(huán)引用的時(shí),就會(huì)把其投入到根緩沖區(qū),當(dāng)根緩沖區(qū)達(dá)到配置文件中的指定數(shù)量后,就會(huì)進(jìn)行垃圾回收,以此解決循環(huán)引用導(dǎo)致的內(nèi)存泄漏問(wèn)題開(kāi)始引入該機(jī)制 php垃圾回收機(jī)制,對(duì)于PHPer來(lái)說(shuō)是一個(gè)不陌生但是又不是很熟悉的內(nèi)容。那么php是怎么實(shí)現(xiàn)對(duì)不需要的內(nèi)存進(jìn)行回收的呢? php變量的內(nèi)部存儲(chǔ)結(jié)構(gòu) 首先還是...

    light 評(píng)論0 收藏0
  • 人人都要知道的PHP底層運(yùn)行機(jī)制與工作原理

    摘要:弱類(lèi)型語(yǔ)言一個(gè)變量的類(lèi)型并不是一開(kāi)始就確定不變的,運(yùn)行中才會(huì)確定并可能發(fā)生隱式或顯示的類(lèi)型轉(zhuǎn)換。引擎組件的模式降低內(nèi)部耦合。 一、PHP設(shè)計(jì)理念及特點(diǎn) 多進(jìn)程模型:由于PHP是多進(jìn)程模型,不同請(qǐng)求間互不干涉,這樣保證了一個(gè)請(qǐng)求掛掉不會(huì)對(duì)全盤(pán)服務(wù)造成影響,PHP也早支持多線程模型。弱類(lèi)型語(yǔ)言:一個(gè)變量的類(lèi)型并不是一開(kāi)始就確定不變的,運(yùn)行中才會(huì)確定并可能發(fā)生隱式或顯示的類(lèi)型轉(zhuǎn)換。引擎(Ze...

    ZHAO_ 評(píng)論0 收藏0
  • 如何"有計(jì)劃,高效率,優(yōu)簡(jiǎn)歷"應(yīng)對(duì)面試

    摘要:雖然有了十全的計(jì)劃,但如何高效率去記住上面那么多東西是一個(gè)大問(wèn)題,看看我是怎么做的。 前言 前一篇文章講述了我在三月份毫無(wú)準(zhǔn)備就去面試的后果,一開(kāi)始心態(tài)真的爆炸,但是又不服氣,一想到每次回來(lái)后家人朋友問(wèn)我面試結(jié)果的期待臉,越覺(jué)得必須付出的行動(dòng)來(lái)證明自己了。 面經(jīng)傳送門(mén):一個(gè)1年工作經(jīng)驗(yàn)的PHP程序員是如何被面試官虐的? 下面是我花費(fèi)兩個(gè)星期做的準(zhǔn)備,主要分三部分: 有計(jì)劃——計(jì)劃好...

    gyl_coder 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<