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

資訊專欄INFORMATION COLUMN

php底層原理之函數(shù)

rose / 975人閱讀

摘要:但是到底是如何找到對(duì)應(yīng)的函數(shù)的呢今天,我們來(lái)一起尋找答案函數(shù)分類首先,我們先回顧一下的函數(shù)分類,函數(shù)包含用戶自定義函數(shù)內(nèi)部函數(shù)匿名函數(shù)等多種類型。用戶自定義函數(shù)和內(nèi)部函數(shù)編譯完成后會(huì)將函數(shù)名注冊(cè)到全局函數(shù)列表中。

對(duì)于PHPer而言,我們通常會(huì)把常用的功能封裝成一個(gè)函數(shù)來(lái)進(jìn)行復(fù)用,以提升開(kāi)發(fā)效率。但是php到底是如何找到對(duì)應(yīng)的函數(shù)的呢?今天,我們來(lái)一起尋找答案~
函數(shù)分類

首先,我們先回顧一下php的函數(shù)分類,php函數(shù)包含用戶自定義函數(shù)、內(nèi)部函數(shù)、匿名函數(shù)等多種類型。而對(duì)于用戶自定義函數(shù)和內(nèi)部函數(shù),他們分別存在對(duì)應(yīng)自己的數(shù)據(jù)結(jié)構(gòu),但是Zend引擎為了適配兩種函數(shù)類型,所以定義了一種新的數(shù)據(jù)結(jié)構(gòu):zend_function聯(lián)合體

數(shù)據(jù)結(jié)構(gòu)

我們還是先看下zend_function聯(lián)合體,了解下為什么針對(duì)用戶自定義函數(shù)和內(nèi)部函數(shù)要做適配

typedef union _zend_function {
    zend_uchar type;    //函數(shù)類型,用來(lái)標(biāo)記是用戶自定義函數(shù)還是內(nèi)部函數(shù)
    struct {
        zend_uchar type;  /* never used */
        char *function_name;    //函數(shù)名稱
        zend_class_entry *scope; //函數(shù)所在的類作用域,用來(lái)標(biāo)記作為成員方法時(shí)所屬的類
        zend_uint fn_flags;     // 標(biāo)記其作為類的成員方法時(shí)的訪問(wèn)類型,是public、protected還是private
        union _zend_function *prototype;  //函數(shù)原型,標(biāo)記內(nèi)部函數(shù)或者用戶自定義函數(shù)所屬的zend_function
        zend_uint num_args;     //函數(shù)的參數(shù)數(shù)量
        zend_uint required_num_args; //必傳的參數(shù)數(shù)量
        zend_arg_info *arg_info;  //參數(shù)信息指針
        zend_bool pass_rest_by_reference;
        unsigned char return_reference;  //返回值 
    } common;
    zend_op_array op_array;   //用戶自定義函數(shù)結(jié)構(gòu)體
    zend_internal_function internal_function; //內(nèi)部函數(shù)結(jié)構(gòu)體
} zend_function;
struct _zend_op_array {
    /* Common elements (共有元素)*/
    zend_uchar type;
    char *function_name;        
    zend_class_entry *scope;
    zend_uint fn_flags;
    union _zend_function *prototype;
    zend_uint num_args;
    zend_uint required_num_args;
    zend_arg_info *arg_info;
    zend_bool pass_rest_by_reference;
    unsigned char return_reference;
    /* END of common elements */
 
    zend_bool done_pass_two;
    ....//  其它字段
}
typedef struct _zend_internal_function {
    /* Common elements (共有元素)*/
    zend_uchar type;
    char * function_name;
    zend_class_entry *scope;
    zend_uint fn_flags;
    union _zend_function *prototype;
    zend_uint num_args;
    zend_uint required_num_args;
    zend_arg_info *arg_info;
    zend_bool pass_rest_by_reference;
    unsigned char return_reference;
    /* END of common elements */
 
    void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
    struct _zend_module_entry *module;
} zend_internal_function;

從上面介紹的內(nèi)容,我們可以發(fā)現(xiàn),不管是用戶自定義函數(shù)還是內(nèi)部函數(shù),在底層存儲(chǔ)時(shí)都會(huì)存在共有字段typecommon,所以他們以聯(lián)合體的方式共享內(nèi)存,可以節(jié)省內(nèi)存空間和快速獲取函數(shù)的基本信息,并且如果有需要,可以在一些結(jié)構(gòu)間完美的進(jìn)行強(qiáng)制類型轉(zhuǎn)換。即zend_function可以與zend_op_array互換,zend_function可以與zend_internal_function互換

函數(shù)注冊(cè)

聊完了用戶自定義函數(shù)和內(nèi)部函數(shù)的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ),我們?cè)賮?lái)看下全局函數(shù)列表

全局函數(shù)列表,可以理解成函數(shù)注冊(cè)表,其內(nèi)部實(shí)現(xiàn)是一個(gè)哈希表。用戶自定義函數(shù)和內(nèi)部函數(shù)編譯完成后會(huì)將函數(shù)名注冊(cè)到全局函數(shù)列表中。也就是此時(shí)會(huì)判斷是否全局函數(shù)列表中存在同名函數(shù)

那么用戶自定義函數(shù)和內(nèi)部函數(shù)在存儲(chǔ)到全局函數(shù)列表時(shí)有什么不同呢?

用戶自定義函數(shù):
我們寫(xiě)的php函數(shù)在編譯階段會(huì)經(jīng)過(guò)詞法分析->語(yǔ)法分析->生成中間代碼opcode->執(zhí)行中間代碼的過(guò)程,執(zhí)行中間代碼時(shí),會(huì)將函數(shù)名注冊(cè)到全局函數(shù)列表

內(nèi)部函數(shù):
php啟動(dòng)時(shí),會(huì)加載所有擴(kuò)展模塊,并為擴(kuò)展模塊中每一個(gè)函數(shù)創(chuàng)建一個(gè)zend_internal_function結(jié)構(gòu),并將這個(gè)函數(shù)名注冊(cè)到全局函數(shù)列表

函數(shù)調(diào)用

接下來(lái),我們?cè)賮?lái)看下調(diào)用函數(shù)時(shí),是如何執(zhí)行的呢?

函數(shù)調(diào)用時(shí),首先會(huì)根據(jù)函數(shù)名去全局函數(shù)列表內(nèi)查找是否存在該函數(shù),如果不存在,則會(huì)直接報(bào)出“Call to undefined function xxx()"的錯(cuò)誤信息;如果存在,則獲取該函數(shù)指針對(duì)應(yīng)的函數(shù)結(jié)構(gòu)中的type字段,判斷其函數(shù)類型,如果函數(shù)類型是自定義函數(shù),則調(diào)用zend_execute來(lái)執(zhí)行函數(shù)的zend_op_array內(nèi)容,而如果函數(shù)類型是內(nèi)部函數(shù),則直接調(diào)用zend_internal_function的handle指針指向的擴(kuò)展模塊的C函數(shù)

總結(jié)

到這里,大家應(yīng)該可以找到開(kāi)頭我們提出的問(wèn)題的答案了。其實(shí)就是通過(guò)函數(shù)注冊(cè)到全局函數(shù)列表,然后函數(shù)調(diào)用時(shí),再?gòu)娜趾瘮?shù)列表中查找對(duì)應(yīng)函數(shù)進(jìn)行執(zhí)行來(lái)實(shí)現(xiàn)的;只不過(guò),對(duì)于用戶自定義函數(shù)和內(nèi)部函數(shù)而言,其實(shí)現(xiàn)方式不同,當(dāng)然這也就意味著執(zhí)行效率的不同(當(dāng)然php內(nèi)部函數(shù)執(zhí)行效率更高了,因?yàn)樗鼪](méi)有運(yùn)行時(shí)的編譯階段,相當(dāng)于直接執(zhí)行c語(yǔ)言,所以能用php內(nèi)部函數(shù)的盡量使用內(nèi)部函數(shù))

今天我們就聊到這里了,歡迎大家的手動(dòng)點(diǎn)贊~

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

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

相關(guān)文章

  • 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底層原理數(shù)組實(shí)現(xiàn)

    摘要:數(shù)組是最常用的數(shù)據(jù)類型,同時(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ù)類型,同時(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ì)于結(jié)構(gòu)體中的和字段我們一直都沒(méi)有詳細(xì)介紹過(guò),而這兩個(gè)字段其實(shí)是和變量之間賦值的原理有著密切的關(guān)系的。 上周我們從底層的角度介紹了php變量從生成->常量賦值->銷毀的完整生命周期(不了解的同學(xué)可以翻看一下前面的文章php底層原理之變量(一)),但是我們留了一個(gè)思考,不知道大家有答案了沒(méi),變量之間的賦值在底層又是如何實(shí)現(xiàn)的呢? 變量之間賦值 php變量的zval結(jié)構(gòu),我們已經(jīng)介紹了...

    bladefury 評(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小知識(shí)點(diǎn)

    摘要:那些瑣碎的知識(shí)點(diǎn)作者記錄的的很奇特很難記的知識(shí)點(diǎn)。易錯(cuò)知識(shí)點(diǎn)整理注意和的區(qū)別中和都是輸出的作用,但是兩者之間還是有細(xì)微的差別。今天手頭不忙,總結(jié)一下,分享過(guò)程中掌握的知識(shí)點(diǎn)。 深入理解 PHP 之:Nginx 與 FPM 的工作機(jī)制 這篇文章從 Nginx 與 FPM 的工作機(jī)制出發(fā),探討配置背后的原理,讓我們真正理解 Nginx 與 PHP 是如何協(xié)同工作的。 PHP 那些瑣碎的知識(shí)...

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

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

0條評(píng)論

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