PHP擴展:Zend引擎對擴展中自定義方法的支持機制

    php擴展中用戶自定義的方法有兩大類:一類是函數(獨立存在),一類是方法(依附於類和對象)。本文先說明下函數。
    構造一個新的函數的原理如下:聲明並實現,實現完成後在某些特定的地方寫代碼告訴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引擎註冊該函數
    在所生成的擴展源代碼中有如下類似的結構:
  1. function_entry foo_functions[] = {
  2.     { NULL, NULL, NULL }
  3. };
    這個結構裏面即是用來給擴展註冊自定義函數的地方,我們先寫上註冊的代碼
  1. function_entry foo_functions[] = {
  2.     PHP_FALIAS(foo, foo, NULL)
  3.     { NULL, NULL, NULL }
  4. };
    可以看到增加了一行語句,PHP_FALIAS也是Zend提供的一個宏,PHP_FALIAS的意思是向Zend註冊進去一個函數,同時聲明瞭在php腳本中這個函數的名稱。第一個參數是在普通php腳本中調用的名稱,第二個參數是向Zend註冊的在第一步中聲明的函數名稱,第三個爲NULL和函數的參數傳遞有管,暫時不管它,置爲NULL就可以了。
    和上面相同,PHP_FALIAS也可以使用ZEND_FALIAS代替,換個馬甲而已。
    編譯完成後,就可以這樣調用了:
  1. <?PHP 
  2.   foo();
  3. ?>
     如果我們把PHP_FALIAS(foo,foo,NULL)修改爲 PHP_FALIAS(foo1,foo,NULL), 則可以這樣調用:
  1.    1. <?PHP 
  2.    2.   foo1();
  3.    3. ?>
     宏的含義:
     PHP_FUNCTION(foo)宏展開後,得到的C代碼如下:
  1. zif_foo_echo (ht=0, return_value=0x86c3620, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)
    可以發現該方法被加了前綴zif_,而且多了5個參數。這些參數都是自動添加進去的,具體含義現在不用管它,我們只關注函數名的改變。
    其實,所有類似foo的擴展中自定義的方法最終編譯完成後都會帶上zif_的前綴, 我們通過nm檢查生成的so文件也能夠看出來。

    而PHP_FALIAS(foo,foo,NULL)這個宏呢,會首先把第二個參數添加上zif_的前綴,然後再註冊到Zend的引擎中。通過這個宏完成php腳本中的方法名和Zend引擎中真實的方法名的映射。
   
    zif_的意義:
    可以防止擴展中定義的方法和Zend本身具有的方法重名,起到了命名空間的作用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章