亚洲精品中文字幕无乱码_久久亚洲精品无码AV大片_最新国产免费Av网址_国产精品3级片

php語(yǔ)言 百分網(wǎng)手機(jī)站

php 5.x 擴(kuò)展開(kāi)發(fā)要點(diǎn)

時(shí)間:2020-09-02 14:59:03 php語(yǔ)言 我要投稿

php 5.x 擴(kuò)展開(kāi)發(fā)要點(diǎn)

  導(dǎo)語(yǔ):php 5.x 擴(kuò)展開(kāi)發(fā)要點(diǎn),最近因項(xiàng)目需要開(kāi)發(fā)了一個(gè)windows dll形式的php擴(kuò)展,實(shí)現(xiàn)訪問(wèn)soap webservice。下面就由小編為大家介紹一下php 5.x 擴(kuò)展開(kāi)發(fā)要點(diǎn),歡迎大家閱讀!

  開(kāi)發(fā)環(huán)境是visual studio 2010(VC10)。測(cè)試用了 xampp-win32-5.6.28-1-VC11-installer。

  為什么不直接用php soap擴(kuò)展

  php確實(shí)有一個(gè)php_soap的官方擴(kuò)展,對(duì)soap webservice操作進(jìn)行了封裝。在本案例中,此前博主已經(jīng)用gSOAP對(duì)某個(gè)web service功能進(jìn)行了封裝,發(fā)布了兩個(gè)DLL訪問(wèn)ws接口,實(shí)現(xiàn)數(shù)據(jù)查詢和加載。php擴(kuò)展是在gSOAP開(kāi)發(fā)的DLL基礎(chǔ)上,做進(jìn)一步的封裝。

  除此之外,還可以借助gSOAP封裝的DLL,開(kāi)發(fā)其他語(yǔ)言的擴(kuò)展,例如python module。良好的功能劃分可以提高復(fù)用性,減少工作重復(fù)。

  安裝XAMPP

  安裝的時(shí)候,至少選擇安裝apache和php。

  基本代碼結(jié)構(gòu)

  php以extension的形式提供擴(kuò)展。位于擴(kuò)展功能底層核心的是zend引擎。

  windows需要包含頭文件

  #include "zend_config.w32.h"

  /* include standard header */

  #include "php.h"

  PHP擴(kuò)展的開(kāi)發(fā),主要通過(guò)一組宏定義,完成擴(kuò)展的框架構(gòu)建。例如

  PHP_MINIT_FUNCTION(CustomExt); // module加載。通常是apache啟動(dòng)的時(shí)候

  PHP_MSHUTDOWN_FUNCTION(CustomExt); //module卸載。通常是apache關(guān)閉的時(shí)候。

  PHP_RINIT_FUNCTION(CustomExt); //一般對(duì)應(yīng)一個(gè)php腳本啟動(dòng)的`時(shí)候。

  PHP_RSHUTDOWN_FUNCTION(CustomExt); // 一般對(duì)應(yīng)一個(gè)php腳本退出的時(shí)候。

  而PHP擴(kuò)展中的函數(shù),通過(guò)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);

  核心數(shù)據(jù)結(jié)構(gòu)

  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

  };

  這個(gè)結(jié)構(gòu)引用了擴(kuò)展需要的所有東西。PHP核心引擎通過(guò)這個(gè)結(jié)構(gòu)找到擴(kuò)展,調(diào)用相關(guān)的函數(shù)。

  內(nèi)存管理

  基本原則是在哪個(gè)層次申請(qǐng)的,就在哪個(gè)層次釋放。

  在PHP層面,不要用malloc()函數(shù),用php提供的emalloc()或者pemalloc()。這種方法申請(qǐng)的內(nèi)存在php擴(kuò)展代碼中,不必顯式釋放。php框架對(duì)這些內(nèi)存進(jìn)行了統(tǒng)一的管理。PHP核心可以確保托管內(nèi)存不會(huì)發(fā)生內(nèi)存泄露而危及平臺(tái)的運(yùn)行穩(wěn)定。

  php擴(kuò)展可以調(diào)用第三方DLL中定義的函數(shù),返回一個(gè)新的類實(shí)例。那么這個(gè)類實(shí)例被創(chuàng)建和被析構(gòu)的地方,都應(yīng)該位于第三方DLL,例如不要在php層面用emalloc()為第三方DLL的對(duì)象申請(qǐng)內(nèi)存。

  如果使用EG(persistent_list)導(dǎo)致空指針訪問(wèn)違例,博主建議在MINIT函數(shù)中自定義一個(gè)hashtable。

  資源如何定義和返回

  為了封裝c++結(jié)構(gòu),在PHP中使用自己定義的c++類,需要在php擴(kuò)展中,定義資源resource。每一種資源類型對(duì)應(yīng)著一個(gè)唯一的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函數(shù)中,對(duì)資源進(jìn)行定義。主要是定義了對(duì)應(yīng)的析構(gòu)函數(shù)。例如

  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);

  }

  通過(guò)ZEND_REGISTER_RESOURCE宏,一個(gè)結(jié)構(gòu)被返回到PHP腳本。實(shí)際是一個(gè)指針,其內(nèi)容是完全透明的。

  返回的這個(gè)資源,PHP腳本在后續(xù)可以使用。

  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);

  ......

  }

  通過(guò)ZEND_FETCH_RESOURCE宏,PHP擴(kuò)展代碼得到這個(gè)resource,從zval得到實(shí)際的結(jié)構(gòu)實(shí)例。

  其他事項(xiàng)

  解決http 80端口被占用的問(wèn)題

  windows system后臺(tái)進(jìn)程可能占用了本地80端口,到XAMPP控制面板,config,修改httpd.conf,改成 Listen 8080,監(jiān)聽(tīng)8080端口。

  PHP源碼下載

  下載對(duì)應(yīng)當(dāng)前版本的PHP源碼。例如

  php-5.6.28.tar.gz

  http://php.net/distributions/php-5.6.28.tar.gz

  解壓為 C:xamppphp-5.6.28

  下載依賴包

  需要下載bison。可將相關(guān)文件拷貝到windows系統(tǒng)目錄。

  http://gnuwin32.sourceforge.net/packages/bison.htm

  生成需要的頭文件

  利用VC命令行環(huán)境,在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>buildconf.bat

  C:xamppphp-5.6.28>set PATH=C:Program Filesisonin;%PATH%

  C:xamppphp-5.6.28>configure.bat

  nmake可以不做。這里主要是為了生成構(gòu)建PHP擴(kuò)展所需的頭文件。

  注意:建議使用與xampp完全相同的VC版本,否則需要修改config.w32.h中的PHP_COMPILER_ID與xampp的完全一致。例如apache error.log報(bào)告錯(cuò)誤

  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

  解決辦法是手動(dòng)修改 main/config.w32.h

  #define PHP_COMPILER_ID "VC11"

  -END-

【php 5.x 擴(kuò)展開(kāi)發(fā)要點(diǎn)】相關(guān)文章:

PHP開(kāi)發(fā)安全保護(hù)的要點(diǎn)09-17

PHP擴(kuò)展程序講解09-30

PHP PDO的擴(kuò)展內(nèi)容08-20

php下zmq擴(kuò)展安裝-208-17

PHP常用開(kāi)發(fā)技巧09-19

怎樣編寫(xiě)一個(gè)獨(dú)立的PHP擴(kuò)展09-18

linux下用phpize給PHP動(dòng)態(tài)添加擴(kuò)展09-10

PHP開(kāi)發(fā)安全的技巧09-12

PHP開(kāi)發(fā)環(huán)境的搭建09-10