<ruby id="bdb3f"></ruby>

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

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] ### 靜態擴展 要開發PHP擴展,第一步要下載PHP源代碼,因為里面有開發擴展需要的工具。我下載的是PHP最新版本5.3.3,格式為tar.bz2壓縮包。下載地址為:http://cn.php.net/get/php-5.3.3.tar.bz2/from/a/mirror。 下載后,將源代碼移動到合適的目錄并解壓。解壓命令為: ``` $ tar -jxvf 源碼包名稱 ``` 若下載的是tar.gz壓縮包,解壓命令為 ``` $ tar -zxvf 源碼包名稱 ``` 解壓后,在源代碼目錄中有個ext目錄,這里便是和PHP擴展有關的目錄。進入目錄后用ls查看,可以看到許多已經存在的擴展。下圖是在我的環境下查看的結果: ![](images/screenshot_1529481533465.png) 其中藍色的均是擴展包目錄,其中可以看到我們很熟悉的mysql、iconv和gd等等。而ext_skel是Unix環境下用于自動生成PHP擴展框架的腳本工具,后面我們馬上會用到,ext_skel_win32.php是windows下對應的腳本。 * * * * * ### 開發自己的PHP擴展——say_hello #### 生成擴展組件框架 作為初學者,我們不必了解所有命令參數,實際上,大多數情況下只需要提供第一個參數就可以了,也就是擴展模塊的名字。因此,我們在ext目錄中鍵入如下命令: ``` $ ./ext_skel --extname=say_hello ``` #### say_hello 這時再用ls查看,會發現多了一個“say_hello”目錄,進入這個目錄,會發現ext_skel已經為我們建立好了`say_hello`的基本框架,如下: `config.m4`:這是Unix環境下的Build System配置文件,后面將會通過它生成配置和安裝。 `php_say_hello.h`:這個文件是擴展模塊的頭文件。遵循C語言一貫的作風,這個里面可以放置一些自定義的結構體、全局變量等等。 `say_hello.c`:這個就是擴展模塊的主程序文件了,最終的擴展模塊各個函數入口都在這里。當然,你可以將所有程序代碼都塞到這里面,也可以遵循模塊化思想,將各個功能模塊放到不同文件中。 * * * * * #### 下面的內容主要圍繞這三個文件展開。 開發PHP擴展組件的第一步不是寫實現代碼,而是要先配置好`Build System` 選項。由于我們是在Linux下開發,所以這里的配置主要與`config.m4`有關。 關于`Build System`配置這一塊,要是寫起來能寫一大堆,而且與Unix系統很多東西相關,就算我有興趣寫估計大家也沒興趣看,所以這里我們從略,只揀關鍵地方說一下,關于`config.m4`更多細節可以參考這里。 ` ` 打開生成的config.m4文件,內容大致如下: ``` dnl If your extension references something external, use with: dnl PHP_ARG_WITH(say_hello, for say_hello support, dnl Make sure that the comment is aligned: dnl [ --with-say_hello Include say_hello support]) dnl Otherwise use enable: dnl PHP_ARG_ENABLE(say_hello, whether to enable say_hello support, dnl Make sure that the comment is aligned: dnl [ --enable-say_hello Enable say_hello support]) ``` 我想大家也都能看明白,意思就是“如果你的擴展引用了外部組件,使用…,否則使用…”。我們的`say_hello`擴展并沒有引用外部組件,所以將“Otherwise use enable”下面三行的“dnl”去掉,改為: ``` dnl Otherwise use enable: PHP_ARG_ENABLE(say_hello, whether to enable say_hello support, Make sure that the comment is aligned: [ --enable-say_hello Enable say_hello support]) ``` 保存,這樣關于`Build System`配置就大功告成了。 ` ` 以上可以看成是為開發PHP擴展而做的準備工作,下面就要編寫核心代碼了。上文說過,編寫PHP擴展是基于Zend API和一些宏的,所以如果要編寫核心代碼,我們首先要弄清楚`PHP Extension`的結構。因為一個PHP Extension在C語言層面實際上就是一個`zend_module_entry`結構體,這點可以從“php_say_hello.h”中得到證實。打開“php_say_hello.h”,會看到里面有怎么一行: ``` extern zend_module_entry say_hello_module_entry; ``` `say_hello_module_entry`就是say_hello擴展的C語言對應元素,而關于其類型zend_module_entry的定義可以在PHP源代碼的“Zend/zend_modules.h”文件里找到。 ` ` 寫到這里,我們的任務就明了了: ``` 第一,如果需要在相應時機處理一些東西,那么需要填充各個攔截函數內容; 第二,編寫say_hello的功能函數,并將引用添加到say_hello_functions中。 ``` 因為say_hello擴展在各個生命周期階段并不需要做操作,所以我們只編寫info_func的內容,上文說過,這個函數將在phpinfo()執行時被自動調用,用于顯示擴展的信息。編寫這個函數會用到四個函數: ``` php_info_print_table_start()——開始phpinfo表格。無參數。 php_info_print_table_header()——輸出表格頭。第一個參數是整形,指明頭的列數,然后后面的參數是與列數等量的(char*)類型參數用于指定顯示的文字。 php_info_print_table_row()——輸出表格內容。第一個參數是整形,指明這一行的列數,然后后面的參數是與列數等量的(char*)類型參數用于指定顯示的文字。 php_info_print_table_end()——結束phpinfo表格。無參數。 ``` 下面是“say_hello.c”中需要編寫的info_func的具體代碼: ``` PHP_MINFO_FUNCTION(say_hello) { php_info_print_table_start(); php_info_print_table_header(2, "say_hello support", "enabled"); php_info_print_table_row(2, "author", "Zhang Yang"); /* Replace with your name */ php_info_print_table_end(); /* Remove comments if you have entries in php.ini DISPLAY_INI_ENTRIES(); */ } ``` #### 編寫核心函數 編寫核心函數,總共分為三步:1、使用宏PHP_FUNCTION定義函數體;2、使用宏ZEND_BEGIN_ARG_INFO和ZEND_END_ARG_INFO定義參數信息;3、使用宏PHP_FE將函數加入到say_hello_functions中。下面分步說明。 ``` PHP_FUNCTION(say_hello_func) { char *name; int name_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { return; } php_printf("Hello %s!", name); RETURN_TRUE; } ``` 上文說過,編寫PHP擴展時幾乎所有東西都不能裸寫,而是必須使用相應的宏。從上面代碼可以清楚看到這一點。總體來說,核心函數代碼一般由如下幾部分構成: `定義函數`,這一步通過宏PHP_FUNCTION實現,函數的外部名稱就是宏后面括號里面的名稱。 `聲明并定義局部變量`。 `解析參數`,這一步通過zend_parse_parameters函數實現,這個函數的作用是從函數用戶的輸入棧中讀取數據,然后轉換成相應的函數參數填入變量以供后面核心功能代碼使用。zend_parse_parameters的第一個參數是用戶傳入參數的個數,可以由宏“ZEND_NUM_ARGS() TSRMLS_CC”生成;第二個參數是一個字符串,其中每個字母代表一個變量類型,我們只有一個字符串型變量,所以第二個參數是“s”;最后各個參數需要一些必要的局部變量指針用于存儲數據,下表給出了不同變量類型的字母代表及其所需要的局部變量指針。 `參數解析`完成后就是核心功能代碼,我們這里只是輸出一行字符,php_printf是Zend版本的printf。 最后的返回值也是通過宏實現的。RETURN_TRUE宏是返回布爾值“true”。 使用宏ZEND_BEGIN_ARG_INFO和ZEND_END_ARG_INFO定義參數信息: ``` ZEND_BEGIN_ARG_INFO(arginfo_say_hello_func, 0) ZEND_END_ARG_INFO() ``` 使用宏`PHP_FE`將函數加入到say_hello_functions中 最后,我們需要將剛才定義的函數和參數信息加入到`say_hello_functions`數組里,代碼如下: ``` const zend_function_entry say_hello_functions[] = { PHP_FE(say_hello_func, arginfo_say_hello_func) {NULL, NULL, NULL} }; ``` 這一步就是通過`PHP_EF`宏實現,注意這個數組最后一行必須是{NULL, NULL, NULL} ,請不要刪除。 #### 編譯并安裝擴展 在say_hello目錄下輸入下面命令: ``` $ /usr/bin/phpize $ ./configure $ make $ make install ``` 這樣就完成了say_hello擴展的安裝(如果沒有報錯的話)。 這時如果你去放置php擴展的目錄下,會發現多了一個say_hello.so的文件。 下面就是將其加入到php.ini配置中,然后重啟Apache(如果需要的話)。這些都是PHP基本配置的內容。 #### 擴展測試 這說明擴展已經安裝成功了。然后我們編寫一個測試用PHP腳本: ``` <?php say_hello_func('Zhang Yang'); ?>; ``` [原文鏈接](http://www.php.cn/php-weizijiaocheng-392678.html)
                  <ruby id="bdb3f"></ruby>

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

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看