<pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

          <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

          <p id="bbfd9"></p>

          <p id="bbfd9"><cite id="bbfd9"></cite></p>

            <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

            <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
            <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
            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

                    <pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

                    <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

                    <p id="bbfd9"></p>

                    <p id="bbfd9"><cite id="bbfd9"></cite></p>

                      <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

                      <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
                      <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
                      飘沙影院