程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 淺析PHP Extension開發基礎篇(2)

淺析PHP Extension開發基礎篇(2)

編輯:關於PHP編程

如果你懶得弄清楚PHP擴展包目錄結構的全部內容,那麼裡面有三個文件你必須注意:

config.m4:這是Unix環境下的Build System配置文件,後面將會通過它生成配置和安裝。

php_say_hello.h:這個文件是擴展模塊的頭文件。遵循C語言一貫的作風,這個裡面可以放置一些自定義的結構體、全局變量等等。

say_hello.c:這個就是擴展模塊的主程序文件了,最終的擴展模塊各個函數入口都在這裡。當然,你可以將所有程序代碼都塞到這裡面,也可以遵循模塊化思想,將各個功能模塊放到不同文件中。

下面的內容主要圍繞這三個文件展開。

Unix Build System配置

開發PHP擴展組件的第一步不是寫實現代碼,而是要先配置好Build System選項。由於我們是在Linux下開發,所以這裡的配置主要與config.m4有關。

關於Build System配置這一塊,要是寫起來能寫一大堆,而且與Unix系統很多東西相關,就算我有興趣寫估計大家也沒興趣看,所以這裡我們從略,只揀關鍵地方說一下,關於config.m4更多細節可以參考這裡。

打開生成的config.m4文件,內容大致如下:

dnl $Id___FCKpd___4nbsp;   dnl config.m4 for extension say_hello    dnl Comments in this file start with the string dnl.    dnl Remove where necessary. This file will not work     dnl without editing.     dnl If your extension references something external, use with:    dnl PHP_ARG_WITH(say_hello, for say_hello support,    dnl Make sure that the comment is aligned:    dnl [  --with-say_hello             Include say_hello support])    dnl Otherwise use enable:    dnl PHP_ARG_ENABLE(say_hello, whether to enable say_hello support,    dnl Make sure that the comment is aligned:    dnl [  --enable-say_hello           Enable say_hello support])    if test "$PHP_SAY_HELLO" != "no"; then    dnl Write more examples of tests here...     dnl # --with-say_hello -> check with-path     dnl SEARCH_PATH="/usr/local /usr"     # you might want to change this     dnl SEARCH_FOR="/include/say_hello.h"  # you most likely want to change this    dnl if test -r $PHP_SAY_HELLO/$SEARCH_FOR; then # path given as parameter     dnl   SAY_HELLO_DIR=$PHP_SAY_HELLO     dnl else # search default path list    dnl   AC_MSG_CHECKING([for say_hello files in default path])     dnl   for i in $SEARCH_PATH ; do   dnl     if test -r $i/$SEARCH_FOR; then    dnl       SAY_HELLO_DIR=$i     dnl       AC_MSG_RESULT(found in $i)     dnl     fi    dnl   done    dnl fi   dnl     dnl if test -z "$SAY_HELLO_DIR"; then    dnl   AC_MSG_RESULT([not found])     dnl   AC_MSG_ERROR([Please reinstall the say_hello distribution])     dnl fi    dnl # --with-say_hello -> add include path     dnl PHP_ADD_INCLUDE($SAY_HELLO_DIR/include)     dnl # --with-say_hello -> check for lib and symbol presence      dnl LIBNAME=say_hello # you may want to change this       dnl LIBSYMBOL=say_hello # you most likely want to change this      dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,     dnl [     dnl   PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $SAY_HELLO_DIR/lib, SAY_HELLO_SHARED_LIBADD)      dnl   AC_DEFINE(HAVE_SAY_HELLOLIB,1,[ ])      dnl ],[      dnl   AC_MSG_ERROR([wrong say_hello lib version or lib not found])      dnl ],[      dnl   -L$SAY_HELLO_DIR/lib -lm      dnl ])       dnl       dnl PHP_SUBST(SAY_HELLO_SHARED_LIBADD)       PHP_NEW_EXTENSION(say_hello, say_hello.c, $ext_shared)     fi  不要看這麼多,因為所有以“dnl”開頭的全是注釋,所以真正起作用沒幾行。這裡需要配置的只有下面幾行:

 dnl If your extension references something external, use with:     dnl PHP_ARG_WITH(say_hello, for say_hello support,    dnl Make sure that the comment is aligned:    dnl [  --with-say_hello             Include say_hello support])    dnl Otherwise use enable:    dnl PHP_ARG_ENABLE(say_hello, whether to enable say_hello support,    dnl Make sure that the comment is aligned:     dnl [  --enable-say_hello           Enable say_hello support])  我想大家也都能看明白,意思就是“如果你的擴展引用了外部組件,使用…,否則使用…”。我們的say_hello擴展並沒有引用外部組件,所以將“Otherwise use enable”下面三行的“dnl”去掉,改為:

dnl Otherwise use enable:     PHP_ARG_ENABLE(say_hello, whether to enable say_hello support,     Make sure that the comment is aligned:     [  --enable-say_hello           Enable say_hello support])    保存,這樣關於Build System配置就大功告成了。

PHP Extension及Zend_Module結構分析

以上可以看成是為開發PHP擴展而做的准備工作,下面就要編寫核心代碼了。上文說過,編寫PHP擴展是基於Zend API和一些宏的,所以如果要編寫核心代碼,我們首先要弄清楚PHP Extension的結構。因為一個PHP Extension在C語言層面實際上就是一個zend_module_entry結構體,這點可以從“php_say_hello.h”中得到證實。打開“php_say_hello.h”,會看到裡面有怎麼一行:

extern zend_module_entry say_hello_module_entry;  say_hello_module_entry就是say_hello擴展的C語言對應元素,而關於其類型zend_module_entry的定義可以在PHP源代碼的“Zend/zend_modules.h”文件裡找到,下面代碼是zend_module_entry的定義:

typedef struct _zend_module_entry zend_module_entry;     struct _zend_module_entry {        unsigned short size;         unsigned int zend_api;       unsigned char zend_debug;         unsigned char zts;         const struct _zend_ini_entry *ini_entry;         const struct _zend_module_dep *deps;         const char *name;         const struct _zend_function_entry *functions;         int (*module_startup_func)(INIT_FUNC_ARGS);         int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS);         int (*request_startup_func)(INIT_FUNC_ARGS);         int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS);         void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS);         const char *version;         size_t globals_size;     #ifdef ZTS         ts_rsrc_id* globals_id_ptr;     #else  &n

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved