溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

PHP7中Reference有什么用

發(fā)布時(shí)間:2021-06-09 16:48:20 來(lái)源:億速云 閱讀:134 作者:Leah 欄目:開(kāi)發(fā)技術(shù)

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)PHP7中Reference有什么用,文章內(nèi)容豐富且以專(zhuān)業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

try_again:
swtich (Z_TYPE_P(zv)) {
   case IS_TRING:
   break;
   case IS_ARRAY:
   break;
  ...
   case IS_REFERENCE:
   zv = Z_REFVAL_P(zv); //解引用
   goto try_again;
   break;
}

如果大家自己寫(xiě)的擴(kuò)展, 如果忘了考慮這種新的類(lèi)型, 那么就會(huì)導(dǎo)致問(wèn)題.

為什么?
那么既然這種新類(lèi)型會(huì)帶來(lái)這么多問(wèn)題, 那么當(dāng)時(shí)為什么要用把引用變成一種類(lèi)型呢? 為什么不還是使用一個(gè)標(biāo)志位呢?

一句話(huà)來(lái)說(shuō), 就是我們不得不這么做. -_#

前面說(shuō)到, Hashtable直接存儲(chǔ)的是zval, 這樣在符號(hào)表中, 倆個(gè)zval如何共用一個(gè)數(shù)值呢? 對(duì)于字符串等復(fù)雜類(lèi)型來(lái)說(shuō)還好, 我們貌似可以在zend_refcounted結(jié)構(gòu)中加入一個(gè)標(biāo)志位來(lái)表明是引用來(lái)解決, 然而這個(gè)也會(huì)遇到Change On Write帶來(lái)的復(fù)制, 但是我們知道在PHP7中, 一些類(lèi)型是直接存儲(chǔ)在zval中的, 比如IS_LONG, 但是引用類(lèi)型是需要引用計(jì)數(shù)的, 那么對(duì)于一個(gè)是IS_LONG并且又是IS_REFERNCE的zval該如何表示呢?

為此, 我們創(chuàng)造了這個(gè)新的類(lèi)型:

PHP7中Reference有什么用

 如圖所示, 引用是一種新的類(lèi)型:zend_reference, 對(duì)于IS_REFERNCE類(lèi)型的zval, zval.value.ref是一個(gè)指向zend_reference的指針, 它包含了引用計(jì)數(shù)和一個(gè)zval, 具體的zval的值是存在zval.value.ref->val中的.

所以對(duì)于IS_LONG的引用來(lái)說(shuō), 就用一個(gè)類(lèi)型是IS_REFERNCE的zval, 它指向一個(gè)zend_reference, 而這個(gè)zend_reference->val中是一個(gè)類(lèi)型為IS_LONG的zval.

Change On Write
PHP采用引用計(jì)數(shù)來(lái)做簡(jiǎn)單的垃圾回收, 考慮如下的代碼:

<?php
1. $val = "laruence";
2. $ref = &$val;
3. $copy = $val;
?>

$ref和$val是指向同一個(gè)zval的引用, 在PHP5的時(shí)候, 我們是通過(guò)一個(gè)引用計(jì)數(shù)為2, 并且引用標(biāo)志位為1來(lái)表示這種情況, 當(dāng)把$val復(fù)制給$copy(line 3)的時(shí)候, 我們發(fā)現(xiàn)$val是一個(gè)計(jì)數(shù)大于1的引用, 所以要產(chǎn)生Change on write, 也就是分離. 所以我們需要復(fù)制這個(gè)zval.

而在PHP7中, 情況就變得簡(jiǎn)單了很多, 首先在引用賦值給$ref(line 2)的時(shí)候, 生成一個(gè)IS_REFERNCE類(lèi)型, 然后因?yàn)榇藭r(shí)有倆個(gè)變量引用它所以zend_reference這個(gè)結(jié)構(gòu)的引用計(jì)數(shù)zval.value.ref->gc.refcount為2.

再隨后的賦值給$copy(line 3)的時(shí)候, 發(fā)現(xiàn)$val是一個(gè)引用, 于是讓$copy指向的是zval.value.ref->val, 也就是字符串值為laruence的zval, 然后把zval的引用計(jì)數(shù)+1, 也就是zval.value.ref->val.value.str.gc.refcount為2. 并沒(méi)有產(chǎn)生復(fù)制.

從而這就很好的解決了上一章所說(shuō)的PHP5的那個(gè)經(jīng)典的問(wèn)題, 比如我們?cè)赑HP7下運(yùn)行上一章的那個(gè)問(wèn)題, 我們得到的結(jié)果是:

$ php-7.0/sapi/cli/php /tmp/1.php
Used 0.00021380008539
Used 0.00020173048281

上述就是小編為大家分享的PHP7中Reference有什么用了,如果剛好有類(lèi)似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI