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

資訊專欄INFORMATION COLUMN

(PHP7內(nèi)核剖析-6) 函數(shù)

crelaber / 1032人閱讀

摘要:引擎中定義了很多內(nèi)部函數(shù)供用戶在中使用,比如等等,除了引擎中定義的內(nèi)部函數(shù),擴(kuò)展中也提供了大量?jī)?nèi)部函數(shù),我們也可以靈活的通過(guò)擴(kuò)展自行定制。頭部是一個(gè)與完全相同的結(jié)構(gòu)函數(shù)指針,展開(kāi)

1.函數(shù)的存儲(chǔ)結(jié)構(gòu)

typedef union  _zend_function        zend_function;

union _zend_function {
    zend_uchar type;    
    struct {
        zend_uchar type; 
        zend_uchar arg_flags[3];
        uint32_t fn_flags;
        zend_string *function_name;
        zend_class_entry *scope; //成員方法所屬類,面向?qū)ο髮?shí)現(xiàn)中用到
        union _zend_function *prototype;
        uint32_t num_args; //參數(shù)數(shù)量
        uint32_t required_num_args; //必傳參數(shù)數(shù)量
        zend_arg_info *arg_info; //參數(shù)信息
    } common;
    zend_op_array op_array; //自定義函數(shù)(函數(shù)實(shí)際編譯為普通的zend_op_array)
    zend_internal_function internal_function; //內(nèi)部函數(shù)(通過(guò)擴(kuò)展或者內(nèi)核提供的C函數(shù))
};
zend_function.common.xx快速訪問(wèn)到zend_function.zend_op_array.xx及zend_function.zend_internal_function.xx
zend_function.type取到zend_function.op_array.type及zend_function.internal_function.type

PHP在編譯階段將用戶自定義的函數(shù)編譯為獨(dú)立的opcodes,保存在EG(function_table)中,調(diào)用時(shí)重新分配新的zend_execute_data(相當(dāng)于運(yùn)行棧),然后執(zhí)行函數(shù)的opcodes,調(diào)用完再還原到舊的zend_execute_data,繼續(xù)執(zhí)行,EG(function_table)是一個(gè)哈希表,記錄的就是PHP中所有的函數(shù)


2.函數(shù)參數(shù)

函數(shù)參數(shù)在內(nèi)核實(shí)現(xiàn)上與函數(shù)內(nèi)的局部變量實(shí)際是一樣的,提供一個(gè)多帶帶的編號(hào),參數(shù)名稱也在zend_op_array.vars中,編號(hào)首先是從參數(shù)開(kāi)始的,所以按照參數(shù)順序其編號(hào)依次為0、1、2...(轉(zhuǎn)化為相對(duì)內(nèi)存偏移量就是96、112、128...),然后函數(shù)調(diào)用時(shí)首先會(huì)在調(diào)用位置將參數(shù)的value復(fù)制到各參數(shù)各自的位置
//參數(shù)的額外信息
typedef struct _zend_arg_info {
    zend_string *name; //參數(shù)名
    zend_string *class_name;
    zend_uchar type_hint; //顯式聲明的參數(shù)類型,比如(array $param_1)
    zend_uchar pass_by_reference; //是否引用傳參,參數(shù)前加&的這個(gè)值就是1
    zend_bool allow_null; //是否允許為NULL
    zend_bool is_variadic; //是否為可變參數(shù),即...用法,function my_func($a, ...$b){...}
} zend_arg_info;
每個(gè)參數(shù)都有一個(gè)上面的結(jié)構(gòu),所有參數(shù)的結(jié)構(gòu)保存在zend_op_array.arg_info數(shù)組中,這里有一個(gè)地方需要注意:zend_op_array->arg_info數(shù)組保存的并不全是輸入?yún)?shù),如果函數(shù)聲明了返回值類型則也會(huì)為它創(chuàng)建一個(gè)zend_arg_info,這個(gè)結(jié)構(gòu)在arg_info數(shù)組的第一個(gè)位置,這種情況下zend_op_array->arg_info指向的實(shí)際是數(shù)組的第二個(gè)位置,返回值的結(jié)構(gòu)通過(guò)zend_op_array->arg_info[-1]讀取


3.內(nèi)部函數(shù)

內(nèi)部函數(shù)指的是由內(nèi)核、擴(kuò)展提供的C語(yǔ)言編寫的function,這類函數(shù)不需要經(jīng)歷opcode的編譯過(guò)程,所以效率上要高于PHP用戶自定義的函數(shù),調(diào)用時(shí)與普通的C程序沒(méi)有差異。Zend引擎中定義了很多內(nèi)部函數(shù)供用戶在PHP中使用,比如:define、defined、strlen、method_exists、class_exists、function_exists......等等,除了Zend引擎中定義的內(nèi)部函數(shù),PHP擴(kuò)展中也提供了大量?jī)?nèi)部函數(shù),我們也可以靈活的通過(guò)擴(kuò)展自行定制。
//zend_internal_function頭部是一個(gè)與zend_op_array完全相同的common結(jié)構(gòu)
typedef struct _zend_internal_function {
    /* Common elements */
    zend_uchar type;
    zend_uchar arg_flags[3]; /* bitset of arg_info.pass_by_reference */
    uint32_t fn_flags;
    zend_string* function_name;
    zend_class_entry *scope;
    zend_function *prototype;
    uint32_t num_args;
    uint32_t required_num_args;
    zend_internal_arg_info *arg_info;
    /* END of common elements */

    void (*handler)(INTERNAL_FUNCTION_PARAMETERS); //函數(shù)指針,展開(kāi):void (*handler)(zend_execute_data *execute_data, zval *return_value)
    struct _zend_module_entry *module;
    void *reserved[ZEND_MAX_RESERVED_RESOURCES];
} zend_internal_function;

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

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

相關(guān)文章

  • (PHP7內(nèi)核剖析-10) 線程安全

    摘要:中專門為解決線程安全的問(wèn)題抽象出了一個(gè)線程安全資源管理器,實(shí)現(xiàn)原理比較簡(jiǎn)單既然共用資源這么困難那么就干脆不共用,各線程不再共享同一份全局變量,而是各復(fù)制一份,使用數(shù)據(jù)時(shí)各線程各取自己的副本,互不干擾。 1.線程安全資源管理器 PHP的SAPI多數(shù)是單線程環(huán)境,比如cli、fpm、cgi,每個(gè)進(jìn)程只啟動(dòng)一個(gè)主線程,這種模式下是不存在線程安全問(wèn)題的,但是也有多線程的環(huán)境,比如Apache,...

    Achilles 評(píng)論0 收藏0
  • (PHP7內(nèi)核剖析-5) PHP代碼的編譯

    摘要:代碼的編譯的解析過(guò)程任務(wù)就是將代碼轉(zhuǎn)化為數(shù)組,代碼里的所有信息都保存在數(shù)組中,然后將數(shù)組交給引擎執(zhí)行,就是內(nèi)核具體執(zhí)行的命令,比如賦值加減操作函數(shù)調(diào)用等,每一條都對(duì)應(yīng)一個(gè)處理,這些是提前定義好的函數(shù)。 1.PHP代碼的編譯 PHP的解析過(guò)程任務(wù)就是將PHP代碼轉(zhuǎn)化為opcode數(shù)組,代碼里的所有信息都保存在opcode數(shù)組中,然后將opcode數(shù)組交給zend引擎執(zhí)行,opcode就是...

    DevTTL 評(píng)論0 收藏0
  • (PHP7內(nèi)核剖析-7) Zend引擎執(zhí)行過(guò)程

    1.EG(executor_globals/zend_executor_globals) PHP整個(gè)生命周期中最主要的一個(gè)結(jié)構(gòu),是一個(gè)全局變量,在main執(zhí)行前分配(非ZTS下),直到PHP退出,它記錄著當(dāng)前請(qǐng)求全部的信息 showImg(https://segmentfault.com/img/bV8fW0?w=960&h=777); 2.EX(execute_data/zend_execut...

    elisa.yang 評(píng)論0 收藏0
  • (PHP7內(nèi)核剖析-8) 類

    摘要:父類方法為錯(cuò)誤,成員方法不得被重寫。父子類方法靜態(tài)屬性不一致父類方法為非靜態(tài)而子類的是靜態(tài)或相反,錯(cuò)誤。 1.類的結(jié)構(gòu) 類是編譯階段的產(chǎn)物,而對(duì)象是運(yùn)行時(shí)產(chǎn)生的,它們歸屬于不同階段。編譯完成后我們定義的每個(gè)類都會(huì)生成一個(gè)zend_class_entry,它保存著類的全部信息,在執(zhí)行階段所有類相關(guān)的操作都是用的這個(gè)結(jié)構(gòu), struct _zend_class_entry { ch...

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

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

0條評(píng)論

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