PHP函數的實現原理及性能分析
前言
在任何語言中,函數都是最基本的組成單元。對于php的函數,它具有哪些特點?函數調用是怎么實現的?php函數的性能如何,有什么使用建議?本文 將從原理出發進行分析結合實際的性能測試嘗試對這些問題進行回答,在了解實現的同時更好的編寫php程序。同時也會對一些常見的php函數進行介紹。
php函數的分類
在php中,橫向劃分的話,函數分為兩大類: user function(內置函數) 和internal function(內置函數)。前者就是用戶在程序中自定義的一些函數和方法,后者則是php本身提供的各類庫函數(比如sprintf、 array_push等)。用戶也可以通過擴展的方法來編寫庫函數,這個將在后面介紹。對于user function,又可以細分為function(函數)和method(類方法),本文中將就這三種函數分別進行分析和測試。
php函數的實現
一個php函數最終是如何執行,這個流程是怎么樣的呢?
要回答這個問題,我們先來看看php代碼的執行所經過的流程。
從圖1可以看到,php實現了一個典型的動態語言執行過程:拿到一段代碼后,經過詞法解析、語法解析等階段后,源程序會被翻譯成一個個指令 (opcodes),然后ZEND虛擬機順次執行這些指令完成操作。Php本身是用c實現的,因此最終調用的也都是c的函數,實際上,我們可以把php看 做是一個c開發的軟件。
通過上面描述不難看出,php中函數的執行也是被翻譯成了opcodes來調用,每次函數調用實際上是執行了一條或多條指令。
對于每一個函數,zend都通過以下的數據結構來描述
typedef union _zend_function { zend_uchar type; / MUST be the first element of this struct! / struct { zend_uchar type; / never used / 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; } common;zend_op_array op_array; zend_internal_function internal_function;
} zend_function;
typedef struct _zend_function_state { HashTable function_symbol_table; zend_function function; void *reserved[ZEND_MAX_RESERVED_RESOURCES]; } zend_function_state;</pre>
其中type標明了函數的類型:用戶函數、內置函數、重載函數。Common中包含函數的基本信息,包括函數名