日韩天天综合网_野战两个奶头被亲到高潮_亚洲日韩欧美精品综合_av女人天堂污污污_视频一区**字幕无弹窗_国产亚洲欧美小视频_国内性爱精品在线免费视频_国产一级电影在线播放_日韩欧美内地福利_亚洲一二三不卡片区

深入解析php中的foreach問題(4)_PHP教程

編輯Tag賺U幣
教程Tag:暫無Tag,歡迎添加,賺取U幣!

推薦:PHP做好防盜鏈的設(shè)置方法
盜鏈 是指服務(wù)提供商自己不提供服務(wù)的內(nèi)容,通過技術(shù)手段繞過其它有利益的最終用戶界面(如廣告),直接在自己的 網(wǎng)站上向最終用戶提供其它服務(wù)提供商的服務(wù)內(nèi)容,騙取最終用戶的瀏覽和點(diǎn)擊率。受益者不提供資源或提供很少的資源,而真正的服務(wù)提供商卻得不到任何的收 益


可見$tmp = $arr的本質(zhì)就是將array的指針進(jìn)行復(fù)制,然后將array的refcount自動加1.用圖表達(dá)出此時的內(nèi)存,依然只有一份array數(shù)組:
07.png
既然只有一份array,那foreach循環(huán)中修改$tmp的時候,為何$arr沒有跟著改變?
繼續(xù)看PHP源碼中的ZEND_FE_RESET_SPEC_CV_HANDLER函數(shù),這是一個OPCODE HANDLER,它對應(yīng)的OPCODE為FE_RESET。該函數(shù)負(fù)責(zé)在foreach開始之前,將數(shù)組的內(nèi)部指針指向其第一個元素。

復(fù)制代碼 代碼如下:
static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *opline = EX(opline);
zval *array_ptr, **array_ptr_ptr;
HashTable *fe_ht;
zend_object_iterator *iter = NULL;
zend_class_entry *ce = NULL;
zend_bool is_empty = 0;
// 對變量進(jìn)行FE_RESET
if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
array_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
if (array_ptr_ptr == NULL || array_ptr_ptr == &EG(uninitialized_zval_ptr)) {
……
}
// foreach一個object
else if (Z_TYPE_PP(array_ptr_ptr) == IS_OBJECT) {
……
}
else {
// 本例會進(jìn)入該分支
if (Z_TYPE_PP(array_ptr_ptr) == IS_ARRAY) {
// 注意此處的SEPARATE_ZVAL_IF_NOT_REF
// 它會重新復(fù)制一個數(shù)組出來
// 真正分離$tmp和$arr,變成了內(nèi)存中的2個數(shù)組
SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
Z_SET_ISREF_PP(array_ptr_ptr);
}
}
array_ptr = *array_ptr_ptr;
Z_ADDREF_P(array_ptr);
}
} else {
……
}

// 重置數(shù)組內(nèi)部指針
……
}


從代碼中可以看出,真正執(zhí)行變量分離并不是在賦值語句執(zhí)行的時候,而是推遲到了使用變量的時候,這也是Copy On Write機(jī)制在PHP中的實(shí)現(xiàn)。
FE_RESET之后,內(nèi)存的變化如下:
08.png

上 圖解釋了為何foreach并不會對原來的$arr產(chǎn)生影響。至于ref_count以及is_ref的變化情況,感興趣的同學(xué)可以詳細(xì)閱讀 ZEND_FE_RESET_SPEC_CV_HANDLER和ZEND_SWITCH_FREE_SPEC_VAR_HANDLER的具體實(shí)現(xiàn)(均位于 php-src/zend/zend_vm_execute.h中),本文不做詳細(xì)剖析:)

 

分享:如何使用PHP實(shí)現(xiàn)javascript的escape和unescape函數(shù)
前端開發(fā)工程師都知道javascript有編碼函數(shù)escape()和對應(yīng)的解碼函數(shù)unescape(),而php中只有個urlencode和 urldecode,這個編碼和解碼函數(shù)對encodeURI和encodeURIComponent有效,但是對escape的是無效的。 javascript中的escape()函數(shù)和unescape()函數(shù)用戶字符串編碼

共4頁上一頁1234下一頁
來源:模板無憂//所屬分類:PHP教程/更新時間:2013-07-02
相關(guān)PHP教程