我們先來建立一個非常簡單的擴充,這個擴充除了一個將其整形參數作為傳回值的函數外幾乎什麼都沒有。下面(“例3-2 一個簡單的擴充”)就是這個範例的代碼:
例3.2 一個簡單的擴充
/* include standard header */
#include "php.h"
/* declaration of functions to be exported */
ZEND_FUNCTION(first_module);
/* compiled function list so Zend knows what's in this module */
zend_function_entry firstmod_functions[] =
{
ZEND_FE(first_module, NULL)
{NULL, NULL, NULL}
};
/* compiled module information */
zend_module_entry firstmod_module_entry =
{
STANDARD_MODULE_HEADER,
"First Module",
firstmod_functions,
NULL,
NULL,
NULL,
NULL,
NULL,
NO_VERSION_YET,
STANDARD_MODULE_PROPERTIES
};
/* implement standard "stub" routine to introduce ourselves to Zend */
#if COMPILE_DL_FIRST_MODULE
ZEND_GET_MODULE(firstmod)
#endif
/* implement function that is meant to be made available to PHP */
ZEND_FUNCTION(first_module)
{
long parameter;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", ¶meter) == FAILURE) {
return;
}
RETURN_LONG(parameter);
}
這段代碼已經包含了一個完整的 PHP 模組。稍後我們會詳細解釋這段代碼,現在讓我們先討論一下構建過程。(在我們討論 API函數前,這可以讓心急的人先實驗一下。)
模組的編譯
模組的編譯基本上有兩種方法:
1、在 Ext 目錄內使用“make” 機制,這種機制也可以編譯出動態可載入模組。
2、手動編譯原始碼。
第一種方法明顯受到人們的偏愛。自 PHP 4.0 以來,這也被標準化成了一個的複雜的構建過程。這種複雜性也導致了難於被理解這個缺點。在本章最後我們會更詳細的討論這些內容,但現在還是讓我們使用預設的 make 檔案吧。
第二種方法很適合那些(因為某種原因而)沒有完整 PHP 源碼樹的或者是很喜歡敲鍵盤的人。雖然這些情況是比較罕見,但為了內容的完整性我們也會介紹一下這種方法。
使用 make 進行編譯
為了能夠使用這種標準機制流程來編譯這些代碼,讓我們把它所有的子目錄都複製到 PHP 源碼樹的 Ext 目錄下。然後運行 buildconf 命令,這將會建立一個新的包含了與我們的擴充相對應的選項的 configure 指令碼。預設情況下,範例中的所有代碼都是未啟用的,因此你不用擔心會破壞你的構建程式。在 buildconf 執行完畢後,再使用 configure –help 命令就會顯示出下面的附加模組:
–enable-array_experiments BOOK: Enables array experiments
–enable-call_userland BOOK: Enables userland module
–enable-cross_conversion BOOK: Enables cross-conversion module
–enable-first_module BOOK: Enables first module
–enable-infoprint BOOK: Enables infoprint module
–enable-reference_test BOOK: Enables reference test module
–enable-resource_test BOOK: Enables resource test module
–enable-variable_creation BOOK: Enables variable-creation module
前面範例(“例3-2 一個簡單的擴充”)中的模組(first_module)可以使用–enable-first_module 或 –enable-first_module=yes 來啟用。
手動編譯
手動編譯需要運行以下命令:
動作 |
命令 |
編譯 |
cc -fpic -DCOMPILE_DL=1 -I/usr/local/include -I. -I.. -I../Zend -c -o <your_object_file> <your_c_file> |
串連 |
cc -shared -L/usr/local/lib -rdynamic -o <your_module_file> <your_object_file(s)> |
編譯命令只是簡單的讓編譯器產生一些中間代碼(不要忽略了-fpic 參數),然後又定義了COMPILE_DL 常量來通知代碼這是要編譯為一個動態可載入的模組(通常用來測試,我們稍後會討論它)。這些選項後面是一些編譯這些原始碼所必須包含的庫檔案目錄。
注意:本例中所有 include 的路徑都是都是Ext 目錄的相對路徑。如果您是在其他目錄編譯的這些源檔案,那麼還要相應的修改路徑名。編譯所需要的目錄有 PHP 目錄,Zend 目錄和模組所在的目錄(如果有必要的話)。
串連命令也是一個非常簡單的把模組串連成一個動態模組的命令。
你可以在編譯指令中加入最佳化選項,儘管這些已經在範例中忽略了(不過你還是可以從前面討論的make 模版檔案中發現一些)。
注意,手動將模組靜態編譯和串連到 PHP 二進位代碼的指令很長很長,因此我們在這裡不作討論。(手動輸入那些指令是很低效的。)