構造一個新的函數的原理如下:聲明並實現,實現完成後在某些特定的地方寫代碼告訴Zend引擎(註冊)。完成這兩步後就可以了。
假如需要實現一個foo()的方法,可以直接在php腳本中調用: php -r "foo();"
第一步:聲明和實現
聲明和實現使用PHP_FUNCTION(foo){...}或者ZEND_FUNTION(foo){...},這兩個宏的作用完全相同,區別在於較老版本的php擴展都是使用PHP_FUNCTION,新的擴展使用ZEND_FUNTION,換了個馬甲。
在宏的{...},可以完成具體的業務邏輯,比如最簡單的輸入一個字符串什麼的。
ZEND_FUNTION(foo){php_printf("hello foo/n");}
這樣即完成了函數的聲明和實現。
第二步:向Zend引擎註冊該函數
在所生成的擴展源代碼中有如下類似的結構:
- function_entry foo_functions[] = {
- { NULL, NULL, NULL }
- };
- function_entry foo_functions[] = {
- PHP_FALIAS(foo, foo, NULL)
- { NULL, NULL, NULL }
- };
和上面相同,PHP_FALIAS也可以使用ZEND_FALIAS代替,換個馬甲而已。
編譯完成後,就可以這樣調用了:
- <?PHP
- foo();
- ?>
- 1. <?PHP
- 2. foo1();
- 3. ?>
PHP_FUNCTION(foo)宏展開後,得到的C代碼如下:
- zif_foo_echo (ht=0, return_value=0x86c3620, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)
其實,所有類似foo的擴展中自定義的方法最終編譯完成後都會帶上zif_的前綴, 我們通過nm檢查生成的so文件也能夠看出來。
而PHP_FALIAS(foo,foo,NULL)這個宏呢,會首先把第二個參數添加上zif_的前綴,然後再註冊到Zend的引擎中。通過這個宏完成php腳本中的方法名和Zend引擎中真實的方法名的映射。
zif_的意義:
可以防止擴展中定義的方法和Zend本身具有的方法重名,起到了命名空間的作用。