php 5.x 擴充套件開發要點
導語:php 5.x 擴充套件開發要點,最近因專案需要開發了一個windows dll形式的php擴充套件,實現訪問soap webservice。下面就由小編為大家介紹一下php 5.x 擴充套件開發要點,歡迎大家閱讀!
開發環境是visual studio 2010(VC10)。測試用了 xampp-win32-5.6.28-1-VC11-installer。
為什麼不直接用php soap擴充套件
php確實有一個php_soap的官方擴充套件,對soap webservice操作進行了封裝。在本案例中,此前博主已經用gSOAP對某個web service功能進行了封裝,釋出了兩個DLL訪問ws介面,實現資料查詢和載入。php擴充套件是在gSOAP開發的DLL基礎上,做進一步的封裝。
除此之外,還可以藉助gSOAP封裝的DLL,開發其他語言的擴充套件,例如python module。良好的功能劃分可以提高複用性,減少工作重複。
安裝XAMPP
安裝的時候,至少選擇安裝apache和php。
基本程式碼結構
php以extension的.形式提供擴充套件。位於擴充套件功能底層核心的是zend引擎。
windows需要包含標頭檔案
#include "zend_config.w32.h"
/* include standard header */
#include "php.h"
PHP擴充套件的開發,主要通過一組巨集定義,完成擴充套件的框架構建。例如
PHP_MINIT_FUNCTION(CustomExt); // module載入。通常是apache啟動的時候
PHP_MSHUTDOWN_FUNCTION(CustomExt); //module解除安裝。通常是apache關閉的時候。
PHP_RINIT_FUNCTION(CustomExt); //一般對應一個php指令碼啟動的時候。
PHP_RSHUTDOWN_FUNCTION(CustomExt); // 一般對應一個php指令碼退出的時候。
而PHP擴充套件中的函式,通過PHP_FUNCTION定義。例如
PHP_FUNCTION(paradb_wsquery_new);
PHP_FUNCTION(paradb_wsquery_prepare);
PHP_FUNCTION(paradb_wsquery_query);
PHP_FUNCTION(paradb_anytype_print);
PHP_FUNCTION(paradb_wsload_new);
PHP_FUNCTION(paradb_wsload_prepare);
PHP_FUNCTION(paradb_wsload_load);
核心資料結構
zend_module_entry CustomExtModule_module_entry = {
STANDARD_MODULE_HEADER,
"CustomExt Module",
CustomExtModule_functions,
PHP_MINIT(CustomExt),
PHP_MSHUTDOWN(CustomExt),
PHP_RINIT(CustomExt),
PHP_RSHUTDOWN(CustomExt),
NULL,
NO_VERSION_YET, STANDARD_MODULE_PROPERTIES
};
這個結構引用了擴充套件需要的所有東西。PHP核心引擎通過這個結構找到擴充套件,呼叫相關的函式。
記憶體管理
基本原則是在哪個層次申請的,就在哪個層次釋放。
在PHP層面,不要用malloc()函式,用php提供的emalloc()或者pemalloc()。這種方法申請的記憶體在php擴充套件程式碼中,不必顯式釋放。php框架對這些記憶體進行了統一的管理。PHP核心可以確保託管記憶體不會發生記憶體洩露而危及平臺的執行穩定。
php擴充套件可以呼叫第三方DLL中定義的函式,返回一個新的類例項。那麼這個類例項被建立和被析構的地方,都應該位於第三方DLL,例如不要在php層面用emalloc()為第三方DLL的物件申請記憶體。
如果使用EG(persistent_list)導致空指標訪問違例,博主建議在MINIT函式中自定義一個hashtable。
資源如何定義和返回
為了封裝c++結構,在PHP中使用自己定義的c++類,需要在php擴充套件中,定義資源resource。每一種資源型別對應著一個唯一的int。例如
int le_paradb_wsquery, le_paradb_xsdany;
#define PHP_PARADB_WSQUERY_RES_NAME "paradb wsquery"
#define PHP_GSOAP_XSD_ANYTYPE_RES_NAME "gsoap xsdany"
#define PHP_PARADB_WSLOAD_RES_NAME "paradb wsload"
在MINIT函式中,對資源進行定義。主要是定義了對應的解構函式。例如
le_paradb_wsquery = zend_register_list_destructors_ex(php_paradb_wsquery_dtor, NULL, PHP_PARADB_WSQUERY_RES_NAME, module_number);
PHP_FUNCTION(paradb_wsquery_new)
{
WsQuery *q;
char *name;
int name_len;
zval* p;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
RETURN_FALSE;
}
if (name_len < 1) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No endpoint given, WsQuery resource not created.");
RETURN_FALSE;
}
paradbc_wsquery_init2(&q, name);
php_printf("[paradb_wsquery_new %p]
", q);
ZEND_REGISTER_RESOURCE(return_value, q, le_paradb_wsquery);
}
通過ZEND_REGISTER_RESOURCE巨集,一個結構被返回到PHP指令碼。實際是一個指標,其內容是完全透明的。
返回的這個資源,PHP指令碼在後續可以使用。
PHP_FUNCTION(paradb_wsquery_query2)
{
WsQuery *q;
zval *zq;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zq) == FAILURE) {
RETURN_FALSE;
}
ZEND_FETCH_RESOURCE(q, WsQuery*, &zq, -1, PHP_PARADB_WSQUERY_RES_NAME, le_paradb_wsquery);
......
}
通過ZEND_FETCH_RESOURCE巨集,PHP擴充套件程式碼得到這個resource,從zval得到實際的結構例項。
其他事項
解決http 80埠被佔用的問題
windows system後臺程序可能佔用了本地80埠,到XAMPP控制面板,config,修改,改成 Listen 8080,監聽8080埠。
PHP原始碼下載
下載對應當前版本的PHP原始碼。例如
解壓為 C:xamppphp-5.6.28
下載依賴包
需要下載bison。可將相關檔案拷貝到windows系統目錄。
生成需要的標頭檔案
利用VC命令列環境,在PHP原始碼目錄做一次configure操作。
Setting environment for using Microsoft Visual Studio 2010 x86 tools.
C:Program Files (x86)Microsoft Visual Studio 10.0VC>cd /d C:xamppphp-5.6.28
C:xamppphp-5.6.28>
C:xamppphp-5.6.28>set PATH=C:Program Filesisonin;%PATH%
C:xamppphp-5.6.28>
nmake可以不做。這裡主要是為了生成構建PHP擴充套件所需的標頭檔案。
注意:建議使用與xampp完全相同的VC版本,否則需要修改config.w32.h中的PHP_COMPILER_ID與xampp的完全一致。例如apache 報告錯誤
PHP Warning: PHP Startup: CustomExt Module: Unable to initialize module
Module compiled with build ID=API20131226,TS,VC10
PHP compiled with build ID=API20131226,TS,VC11
These options need to match
解決辦法是手動修改 main/config.w32.h
#define PHP_COMPILER_ID "VC11"
-END-
-
PHP考試筆試題
用寶珠打扮自己,不如用知識充實自己。以下是小編為大家搜尋整理的PHP考試筆試題,希望能給大家帶來幫助!更多精彩內容請及時關注我們應屆畢業生考試網!1、{PHP題目}識別符號是變數的名稱。PHP中的識別符號用$+變數名來表示。識別符號在PHP中遵循下列選項中的那些規則?()...
-
用PHP讀取檔案的正確方法
處理諸如PHP之類的現代程式語言的樂趣之一就是有大量的選項可用。PHP可以輕鬆地贏得Perl的座右銘There‘smorethanonewaytodoit(並非只有一種方法可做這件事),尤其是在檔案處理上。但是在這麼多可用的選項中,哪一種是完成作業的最佳工具?當然,實際答案取決於...
-
編譯chm格式PHP手冊的方法
微軟的chm檔案格式是很受我們喜愛的,因為它可以把很多HTML檔案打包成一個檔案,容易傳輸和分享。而且非常方便易用,支援索引、搜尋等。正因為這樣,大家通常都使用chm版本的PHP手冊。php.net會定期編譯PHP手冊,提供各種版本供大家下載,包括chm格式。由於是定期編譯,所以...
-
PHP常用函式總結
PHP的常用函式有哪些呢?下面是由本站小編為大家整理的PHP常用函式總結,喜歡的可以收藏一下!瞭解更多詳情資訊,請關注應屆畢業生考試網!數學函式():求絕對值$abs=abs(-4.2);//4.2數字絕對值數字():進一法取整echoceil(9.999);//10浮點數進一取整r():捨去法取整ech...