成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

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

crelaber / 1041人閱讀

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

1.函數(shù)的存儲結(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ū)ο髮崿F(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ù)實際編譯為普通的zend_op_array)
    zend_internal_function internal_function; //內(nèi)部函數(shù)(通過擴(kuò)展或者內(nèi)核提供的C函數(shù))
};
zend_function.common.xx快速訪問到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)用時重新分配新的zend_execute_data(相當(dāng)于運(yùn)行棧),然后執(zhí)行函數(shù)的opcodes,調(diào)用完再還原到舊的zend_execute_data,繼續(xù)執(zhí)行,EG(function_table)是一個哈希表,記錄的就是PHP中所有的函數(shù)


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

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


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

內(nèi)部函數(shù)指的是由內(nèi)核、擴(kuò)展提供的C語言編寫的function,這類函數(shù)不需要經(jīng)歷opcode的編譯過程,所以效率上要高于PHP用戶自定義的函數(shù),調(diào)用時與普通的C程序沒有差異。Zend引擎中定義了很多內(nèi)部函數(shù)供用戶在PHP中使用,比如:define、defined、strlen、method_exists、class_exists、function_exists......等等,除了Zend引擎中定義的內(nèi)部函數(shù),PHP擴(kuò)展中也提供了大量內(nèi)部函數(shù),我們也可以靈活的通過擴(kuò)展自行定制。
//zend_internal_function頭部是一個與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ù)指針,展開: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)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/28589.html

相關(guān)文章

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

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

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

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

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

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

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

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

    JohnLui 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<