PHP7中Reference內(nèi)核的使用

本文以PHP7中Reference內(nèi)核為例,為大家分析PHP7中Reference內(nèi)核的使用方法,閱讀完整文相信大家對PHP7中Reference內(nèi)核的使用有了一定的認(rèn)識。

創(chuàng)新互聯(lián)公司專注于企業(yè)成都全網(wǎng)營銷、網(wǎng)站重做改版、申扎網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5頁面制作、商城網(wǎng)站建設(shè)、集團公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為申扎等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

引用(REFERENCE)在PHP5的時候是一個標(biāo)志位, 而在PHP7以后我們把它變成了一種新的類型:IS_REFERNCE. 然而引用是一種很常見的應(yīng)用, 所以這個變化帶來了很多的變化, 也給我們在做PHP7開發(fā)的時候, 因為有的時候疏忽忘了處理這個類型, 而帶來不少的bug.

最簡單的情況, 就是在處理各種類型的時候, 從此以后我們要多考慮這種新的類型, 比如在PHP7中, 這樣的代碼形式就變得很常見了:

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;}

如果大家自己寫的擴展, 如果忘了考慮這種新的類型, 那么就會導(dǎo)致問題.

為什么?

那么既然這種新類型會帶來這么多問題, 那么當(dāng)時為什么要用把引用變成一種類型呢? 為什么不還是使用一個標(biāo)志位呢?
一句話來說, 就是我們不得不這么做. -_#
前面說到, Hashtable直接存儲的是zval, 這樣在符號表中, 倆個zval如何共用一個數(shù)值呢? 對于字符串等復(fù)雜類型來說還好, 我們貌似可以在zend_refcounted結(jié)構(gòu)中加入一個標(biāo)志位來表明是引用來解決, 然而這個也會遇到Change On Write帶來的復(fù)制, 但是我們知道在PHP7中, 一些類型是直接存儲在zval中的, 比如IS_LONG, 但是引用類型是需要引用計數(shù)的, 那么對于一個是IS_LONG并且又是IS_REFERNCE的zval該如何表示呢?
為此, 我們創(chuàng)造了這個新的類型:
PHP7中Reference內(nèi)核的使用如圖所示, 引用是一種新的類型:zend_reference, 對于IS_REFERNCE類型的zval, zval.value.ref是一個指向zend_reference的指針, 它包含了引用計數(shù)和一個zval, 具體的zval的值是存在zval.value.ref->val中的.
所以對于IS_LONG的引用來說, 就用一個類型是IS_REFERNCE的zval, 它指向一個zend_reference, 而這個zend_reference->val中是一個類型為IS_LONG的zval.

Change On Write

PHP采用引用計數(shù)來做簡單的垃圾回收, 考慮如下的代碼:

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

$ref和$val是指向同一個zval的引用, 在PHP5的時候, 我們是通過一個引用計數(shù)為2, 并且引用標(biāo)志位為1來表示這種情況, 當(dāng)把$val復(fù)制給$copy(line 3)的時候, 我們發(fā)現(xiàn)$val是一個計數(shù)大于1的引用, 所以要產(chǎn)生Change on write, 也就是分離. 所以我們需要復(fù)制這個zval.
而在PHP7中, 情況就變得簡單了很多, 首先在引用賦值給$ref(line 2)的時候, 生成一個IS_REFERNCE類型, 然后因為此時有倆個變量引用它所以zend_reference這個結(jié)構(gòu)的引用計數(shù)zval.value.ref->gc.refcount為2.
再隨后的賦值給$copy(line 3)的時候, 發(fā)現(xiàn)$val是一個引用, 于是讓$copy指向的是zval.value.ref->val, 也就是字符串值為laruence的zval, 然后把zval的引用計數(shù)+1, 也就是zval.value.ref->val.value.str.gc.refcount為2. 并沒有產(chǎn)生復(fù)制.
從而這就很好的解決了上一章所說的PHP5的那個經(jīng)典的問題, 比如我們在PHP7下運行上一章的那個問題, 我們得到的結(jié)果是:

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

可見確實沒有發(fā)生復(fù)制, 從而不會產(chǎn)生任何的性能問題.

關(guān)于PHP7中Reference內(nèi)核的使用就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

網(wǎng)站題目:PHP7中Reference內(nèi)核的使用
網(wǎng)站地址:http://muchs.cn/article36/gdcisg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、網(wǎng)站收錄、微信小程序微信公眾號、定制網(wǎng)站、Google

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)