<address id="ousso"></address>
<form id="ousso"><track id="ousso"><big id="ousso"></big></track></form>
  1. php語言

    php 5.x 擴展開發要點

    時間:2025-03-12 09:04:38 php語言 我要投稿
    • 相關推薦

    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,修改httpd.conf,改成 Listen 8080,監聽8080端口。

      PHP源碼下載

      下載對應當前版本的PHP源碼。例如

      php-5.6.28.tar.gz

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

      解壓為 C:xamppphp-5.6.28

      下載依賴包

      需要下載bison。可將相關文件拷貝到windows系統目錄。

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

      生成需要的頭文件

      利用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>buildconf.bat

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

      C:xamppphp-5.6.28>configure.bat

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

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

      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 5.x 擴展開發要點】相關文章:

    PHP開發安全保護的要點04-29

    PHP PDO的擴展內容06-21

    PHP擴展程序講解04-12

    php內核分析之擴展01-31

    php下zmq擴展安裝-207-20

    怎么用PHP安裝memcached擴展筆記01-31

    怎么在yaf框架增加php擴展框架07-24

    linux下用phpize給PHP動態添加擴展07-25

    怎樣編寫一個獨立的PHP擴展03-15

    <address id="ousso"></address>
    <form id="ousso"><track id="ousso"><big id="ousso"></big></track></form>
    1. 日日做夜狠狠爱欧美黑人