精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

淺析PHP Extension開發(fā)基礎(chǔ)篇

開發(fā) 后端
今天我們將介紹的是PHP當中比較出名的PHP Extension開發(fā)基礎(chǔ)篇,開發(fā)環(huán)境是Ubuntu 10.04 + PHP 5.3.3。

PHP是當前應(yīng)用非常廣泛的一門語言,從國外的Facebook、Twitter到國內(nèi)的淘寶、騰訊、百度再到互聯(lián)網(wǎng)上林林總總的各種大中小型網(wǎng)站都能見到它的身影。PHP的成功,應(yīng)該說很大程度上依賴于其開放的擴展API機制和豐富的擴展組件(PHP Extension),正是這些擴展組件使得PHP從各種數(shù)據(jù)庫操作到XML、JSON、加密、文件處理、圖形處理、Socket等領(lǐng)域無所不能。有時候開發(fā)人員可能需要開發(fā)自己的PHP擴展,當前PHP5的擴展機制是基于Zend API的,Zend API提供了豐富的接口和宏定義,加上一些實用工具,使得PHP擴展開發(fā)起來難度并不算特別大。本文將介紹關(guān)于PHP擴展組件開發(fā)的基本知識,并通過一個實例展示開發(fā)PHP擴展的基本過程。

PHP擴展組件的開發(fā)過程在Unix和Windows環(huán)境下有所不同,但基本是互通的,本文將基于Unix環(huán)境(具體使用Linux)。閱讀本文需要簡單了解Unix環(huán)境、PHP和C語言的一些基礎(chǔ)知識,只要簡單了解就行,我會盡量不涉及太過具體的操作系統(tǒng)和語言特性,并在必要的地方加以解釋,以便讀者閱讀。

本文的具體開發(fā)環(huán)境為Ubuntu 10.04 + PHP 5.3.3。

下載PHP源代碼

要開發(fā)PHP擴展,第一步要下載PHP源代碼,因為里面有開發(fā)擴展需要的工具。我下載的是PHP最新版本5.3.3,格式為tar.bz2壓縮包。下載地址為:http://cn.php.net/get/php-5.3.3.tar.bz2/from/a/mirror

下載后,將源代碼移動到合適的目錄并解壓。解壓命令為:

  1. tar -jxvf 源碼包名稱  

若下載的是tar.gz壓縮包,解壓命令為

  1. tar -zxvf 源碼包名稱  

解壓后,在源代碼目錄中有個ext目錄,這里便是和PHP擴展有關(guān)的目錄。進入目錄后用ls查看,可以看到許多已經(jīng)存在的擴展。下圖是在我的環(huán)境下查看的結(jié)果:

image

其中藍色的均是擴展包目錄,其中可以看到我們很熟悉的mysql、iconv和gd等等。而ext_skel是Unix環(huán)境下用于自動生成PHP擴展框架的腳本工具,后面我們馬上會用到,ext_skel_win32.php是windows下對應(yīng)的腳本。

開發(fā)自己的PHP擴展——say_hello

下面我們開發(fā)一個PHP擴展:say_hello。這個擴展很簡單,只是接受一個字符串參數(shù),然后輸出“Hello xxx!”。這個例子只是為了介紹PHP擴展組件的開發(fā)流程,不承擔實際功能。

生成擴展組件框架

PHP的擴展組件開發(fā)目錄和文件是有固定組織結(jié)構(gòu)的,你可以隨便進入一個已有擴展組件目錄,查看其所有文件,我想你一定眼花繚亂了。當然你可以選擇手工完成框架的搭建,不過我相信你更希望有什么東西來幫你完成。上文提到的ext_skel腳本就是用來自動構(gòu)建擴展包框架的工具。ext_skel的完整命令為:

  1. ext_skel --extname=module [--proto=file] [--stubs=file] [--xml[=file]] [--skel=dir] [--full-xml] [--no-help]  

作為初學者,我們不必了解所有命令參數(shù),實際上,大多數(shù)情況下只需要提供第一個參數(shù)就可以了,也就是擴展模塊的名字。因此,我們在ext目錄中鍵入如下命令:

  1. /ext_skel --extname=say_hello  

(如果你希望詳細了解ext_skel的各項命令參數(shù),請參考這里

這時再用ls查看,會發(fā)現(xiàn)多了一個“say_hello”目錄,進入這個目錄,會發(fā)現(xiàn)ext_skel已經(jīng)為我們建立好了say_hello的基本框架,如下圖:

image

如果你懶得弄清楚PHP擴展包目錄結(jié)構(gòu)的全部內(nèi)容,那么里面有三個文件你必須注意:

config.m4:這是Unix環(huán)境下的Build System配置文件,后面將會通過它生成配置和安裝。

php_say_hello.h:這個文件是擴展模塊的頭文件。遵循C語言一貫的作風,這個里面可以放置一些自定義的結(jié)構(gòu)體、全局變量等等。

say_hello.c:這個就是擴展模塊的主程序文件了,最終的擴展模塊各個函數(shù)入口都在這里。當然,你可以將所有程序代碼都塞到這里面,也可以遵循模塊化思想,將各個功能模塊放到不同文件中。

下面的內(nèi)容主要圍繞這三個文件展開。

Unix Build System配置

開發(fā)PHP擴展組件的第一步不是寫實現(xiàn)代碼,而是要先配置好Build System選項。由于我們是在Linux下開發(fā),所以這里的配置主要與config.m4有關(guān)。

關(guān)于Build System配置這一塊,要是寫起來能寫一大堆,而且與Unix系統(tǒng)很多東西相關(guān),就算我有興趣寫估計大家也沒興趣看,所以這里我們從略,只揀關(guān)鍵地方說一下,關(guān)于config.m4更多細節(jié)可以參考這里

打開生成的config.m4文件,內(nèi)容大致如下:

  1. dnl $Id$    
  2. dnl config.m4 for extension say_hello    
  3. dnl Comments in this file start with the string 'dnl'.    
  4. dnl Remove where necessary. This file will not work    
  5.  dnl without editing.    
  6.  dnl If your extension references something external, use with:    
  7. dnl PHP_ARG_WITH(say_hello, for say_hello support,    
  8. dnl Make sure that the comment is aligned:    
  9. dnl [  --with-say_hello             Include say_hello support])    
  10. dnl Otherwise use enable:    
  11. dnl PHP_ARG_ENABLE(say_hello, whether to enable say_hello support,    
  12. dnl Make sure that the comment is aligned:    
  13. dnl [  --enable-say_hello           Enable say_hello support])    
  14. if test "$PHP_SAY_HELLO" != "no"; then   
  15.  dnl Write more examples of tests here...    
  16.  dnl # --with-say_hello -> check with-path    
  17.  dnl SEARCH_PATH="/usr/local /usr"     # you might want to change this    
  18.  dnl SEARCH_FOR="/include/say_hello.h"  # you most likely want to change this    
  19. dnl if test -r $PHP_SAY_HELLO/$SEARCH_FOR; then # path given as parameter    
  20.  dnl   SAY_HELLO_DIR=$PHP_SAY_HELLO    
  21.  dnl else # search default path list    
  22. dnl   AC_MSG_CHECKING([for say_hello files in default path])    
  23.  dnl   for i in $SEARCH_PATH ; do   
  24. dnl     if test -r $i/$SEARCH_FOR; then   
  25.  dnl       SAY_HELLO_DIR=$i    
  26.  dnl       AC_MSG_RESULT(found in $i)    
  27.  dnl     fi   
  28.  dnl   done   
  29.  dnl fi   
  30. dnl    
  31.  dnl if test -z "$SAY_HELLO_DIR"; then   
  32.  dnl   AC_MSG_RESULT([not found])    
  33.  dnl   AC_MSG_ERROR([Please reinstall the say_hello distribution])    
  34.  dnl fi   
  35.  dnl # --with-say_hello -> add include path    
  36.  dnl PHP_ADD_INCLUDE($SAY_HELLO_DIR/include)    
  37.  dnl # --with-say_hello -> check for lib and symbol presence    
  38.   dnl LIBNAME=say_hello # you may want to change this    
  39.    dnl LIBSYMBOL=say_hello # you most likely want to change this     
  40.  dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,    
  41.  dnl [    
  42.  dnl   PHP_ADD_LIBRARY_WITH_PATH($LIBNAME$SAY_HELLO_DIR/lib, SAY_HELLO_SHARED_LIBADD)    
  43.   dnl   AC_DEFINE(HAVE_SAY_HELLOLIB,1,[ ])    
  44.   dnl ],[    
  45.   dnl   AC_MSG_ERROR([wrong say_hello lib version or lib not found])    
  46.   dnl ],[    
  47.   dnl   -L$SAY_HELLO_DIR/lib -lm    
  48.   dnl ])    
  49.    dnl    
  50.    dnl PHP_SUBST(SAY_HELLO_SHARED_LIBADD)    
  51.    PHP_NEW_EXTENSION(say_hello, say_hello.c, $ext_shared)    
  52.  fi  

不要看這么多,因為所有以“dnl”開頭的全是注釋,所以真正起作用沒幾行。這里需要配置的只有下面幾行:

  1.  dnl If your extension references something external, use with:    
  2.  dnl PHP_ARG_WITH(say_hello, for say_hello support,    
  3. dnl Make sure that the comment is aligned:    
  4. dnl [  --with-say_hello             Include say_hello support])    
  5. dnl Otherwise use enable:    
  6. dnl PHP_ARG_ENABLE(say_hello, whether to enable say_hello support,    
  7. dnl Make sure that the comment is aligned:    
  8.  dnl [  --enable-say_hello           Enable say_hello support])  

我想大家也都能看明白,意思就是“如果你的擴展引用了外部組件,使用…,否則使用…”。我們的say_hello擴展并沒有引用外部組件,所以將“Otherwise use enable”下面三行的“dnl”去掉,改為:

  1. dnl Otherwise use enable:    
  2.  PHP_ARG_ENABLE(say_hello, whether to enable say_hello support,    
  3.  Make sure that the comment is aligned:    
  4.  [  --enable-say_hello           Enable say_hello support])   
  5.  

保存,這樣關(guān)于Build System配置就大功告成了。

PHP Extension及Zend_Module結(jié)構(gòu)分析

以上可以看成是為開發(fā)PHP擴展而做的準備工作,下面就要編寫核心代碼了。上文說過,編寫PHP擴展是基于Zend API和一些宏的,所以如果要編寫核心代碼,我們首先要弄清楚PHP Extension的結(jié)構(gòu)。因為一個PHP Extension在C語言層面實際上就是一個zend_module_entry結(jié)構(gòu)體,這點可以從“php_say_hello.h”中得到證實。打開“php_say_hello.h”,會看到里面有怎么一行:

  1. extern zend_module_entry say_hello_module_entry;  

say_hello_module_entry就是say_hello擴展的C語言對應(yīng)元素,而關(guān)于其類型zend_module_entry的定義可以在PHP源代碼的“Zend/zend_modules.h”文件里找到,下面代碼是zend_module_entry的定義:

  1. typedef struct _zend_module_entry zend_module_entry;    
  2.  struct _zend_module_entry {    
  3.     unsigned short size;    
  4.      unsigned int zend_api;    
  5.    unsigned char zend_debug;    
  6.      unsigned char zts;    
  7.      const struct _zend_ini_entry *ini_entry;    
  8.      const struct _zend_module_dep *deps;    
  9.      const char *name;    
  10.      const struct _zend_function_entry *functions;    
  11.      int (*module_startup_func)(INIT_FUNC_ARGS);    
  12.      int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS);    
  13.      int (*request_startup_func)(INIT_FUNC_ARGS);    
  14.      int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS);    
  15.      void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS);    
  16.      const char *version;    
  17.      size_t globals_size;    
  18.  #ifdef ZTS    
  19.      ts_rsrc_id* globals_id_ptr;    
  20.  #else    
  21.      void* globals_ptr;    
  22.  #endif    
  23.      void (*globals_ctor)(void *global TSRMLS_DC);    
  24.      void (*globals_dtor)(void *global TSRMLS_DC);    
  25.      int (*post_deactivate_func)(void);    
  26.      int module_started;    
  27.      unsigned char type;    
  28.      void *handle;    
  29.      int module_number;    
  30.      char *build_id;    
  31.  };  

這個結(jié)構(gòu)體可能看起來會讓人有點頭疼,不過我還是要解釋一下里面的內(nèi)容。因為這就是PHP Extension的原型,如果不搞清楚,就沒法開發(fā)PHP Extension了。當然,我就不一一對每個字段進行解釋了,只揀關(guān)鍵的、這篇文章會用到的字段說,因為許多字段并不需要我們手工填寫,而是可以使用某些預定義的宏填充。

第7個字段“name”,這個字段是此PHP Extension的名字,在本例中就是“say_hello”。

第8個字段“functions”,這個將存放我們在此擴展中定義的函數(shù)的引用,具體結(jié)構(gòu)不再分析,有興趣的朋友可以閱讀_zend_function_entry的源代碼。具體編寫代碼時這里會有相應(yīng)的宏。

第9-12個字段分別是四個函數(shù)指針,這四個函數(shù)會在相應(yīng)時機被調(diào)用,分別是“擴展模塊加載時”、“擴展模塊卸載時”、“每個請求開始時”和“每個請求結(jié)束時”。這四個函數(shù)可以看成是一種攔截機制,主要用于相應(yīng)時機的資源分配、釋放等相關(guān)操作。

第13個字段“info_func”也是一個函數(shù)指針,這個指針指向的函數(shù)會在執(zhí)行phpinfo()時被調(diào)用,用于顯示自定義模塊信息。

第14個字段“version”是模塊的版本。

(關(guān)于zend_module_entry更詳盡的介紹請參考這里

介紹完以上字段,我們可以看看“say_hello.c”中自動生成的“say_hello_module_entry”框架代碼了。

  1. /* {{{ say_hello_module_entry    
  2.   */   
  3.  zend_module_entry say_hello_module_entry = {    
  4.  #if ZEND_MODULE_API_NO >= 20010901    
  5.      STANDARD_MODULE_HEADER,    
  6.  #endif    
  7.      "say_hello",    
  8.      say_hello_functions,    
  9.      PHP_MINIT(say_hello),    
  10.      PHP_MSHUTDOWN(say_hello),    
  11.      PHP_RINIT(say_hello),       /* Replace with NULL if there's nothing to do at request start */   
  12.      PHP_RSHUTDOWN(say_hello),   /* Replace with NULL if there's nothing to do at request end */   
  13.      PHP_MINFO(say_hello),    
  14.  #if ZEND_MODULE_API_NO >= 20010901    
  15.      "0.1"/* Replace with version number for your extension */   
  16.  #endif    
  17.      STANDARD_MODULE_PROPERTIES    
  18.  };    
  19.  /* }}} */  

首先,宏“STANDARD_MODULE_HEADER”會生成前6個字段,“STANDARD_MODULE_PROPERTIES ”會生成“version”后的字段,所以現(xiàn)在我們還不用操心。而我們關(guān)心的幾個字段,也都填寫好或由宏生成好了,并且在“say_hello.c”的相應(yīng)位置也生成了幾個函數(shù)的框架。這里要注意,幾個宏的參數(shù)均為“say_hello”,但這并不表示幾個函數(shù)的名字全為“say_hello”,C語言中也不可能存在函數(shù)名重載機制。實際上,在開發(fā)PHP Extension的過程中,幾乎處處都要用到Zend里預定義的各種宏,從全局變量到函數(shù)的定義甚至返回值,都不能按照“裸寫”的方式來編寫C語言,這是因為PHP的運行機制可能會導致命名沖突等問題,而這些宏會將函數(shù)等元素變換成一個內(nèi)部名稱,但這些對程序員都是透明的(除非你去閱讀那些宏的代碼),我們通過各種宏進行編程,而宏則為我們處理很多內(nèi)部的東西。

寫到這里,我們的任務(wù)就明了了:第一,如果需要在相應(yīng)時機處理一些東西,那么需要填充各個攔截函數(shù)內(nèi)容;第二,編寫say_hello的功能函數(shù),并將引用添加到say_hello_functions中。

編寫phpinfo()回調(diào)函數(shù)

因為say_hello擴展在各個生命周期階段并不需要做操作,所以我們只編寫info_func的內(nèi)容,上文說過,這個函數(shù)將在phpinfo()執(zhí)行時被自動調(diào)用,用于顯示擴展的信息。編寫這個函數(shù)會用到四個函數(shù):

php_info_print_table_start()——開始phpinfo表格。無參數(shù)。

php_info_print_table_header()——輸出表格頭。第一個參數(shù)是整形,指明頭的列數(shù),然后后面的參數(shù)是與列數(shù)等量的(char*)類型參數(shù)用于指定顯示的文字。

php_info_print_table_row()——輸出表格內(nèi)容。第一個參數(shù)是整形,指明這一行的列數(shù),然后后面的參數(shù)是與列數(shù)等量的(char*)類型參數(shù)用于指定顯示的文字。

php_info_print_table_end()——結(jié)束phpinfo表格。無參數(shù)。

下面是“say_hello.c”中需要編寫的info_func的具體代碼:

  1. /* {{{ PHP_MINFO_FUNCTION    
  2.  */   
  3. PHP_MINFO_FUNCTION(say_hello)    
  4. {    
  5.     php_info_print_table_start();    
  6.     php_info_print_table_header(2, "say_hello support""enabled");    
  7.     php_info_print_table_row(2, "author""Zhang Yang"); /* Replace with your name */   
  8.     php_info_print_table_end();    
  9.     /* Remove comments if you have entries in php.ini    
  10.     DISPLAY_INI_ENTRIES();    
  11.     */   
  12. }    
  13. /* }}} */  
可以看到我們編寫了兩行內(nèi)容、組件是否可用以及作者信息。

編寫核心函數(shù)

編寫核心函數(shù),總共分為三步:1、使用宏P(guān)HP_FUNCTION定義函數(shù)體;2、使用宏ZEND_BEGIN_ARG_INFO和ZEND_END_ARG_INFO定義參數(shù)信息;3、使用宏P(guān)HP_FE將函數(shù)加入到say_hello_functions中。下面分步說明。

使用宏P(guān)HP_FUNCTION定義函數(shù)體

  1. PHP_FUNCTION(say_hello_func)    
  2. {    
  3.     char *name;    
  4.     int name_len;    
  5.     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE)    
  6.     {    
  7.         return;    
  8.     }    
  9.     php_printf("Hello %s!", name);    
  10.    RETURN_TRUE;    
  11. }  

上文說過,編寫PHP擴展時幾乎所有東西都不能裸寫,而是必須使用相應(yīng)的宏。從上面代碼可以清楚看到這一點。總體來說,核心函數(shù)代碼一般由如下幾部分構(gòu)成:

定義函數(shù),這一步通過宏P(guān)HP_FUNCTION實現(xiàn),函數(shù)的外部名稱就是宏后面括號里面的名稱。

聲明并定義局部變量。

解析參數(shù),這一步通過zend_parse_parameters函數(shù)實現(xiàn),這個函數(shù)的作用是從函數(shù)用戶的輸入棧中讀取數(shù)據(jù),然后轉(zhuǎn)換成相應(yīng)的函數(shù)參數(shù)填入變量以供后面核心功能代碼使用。zend_parse_parameters的第一個參數(shù)是用戶傳入?yún)?shù)的個數(shù),可以由宏“ZEND_NUM_ARGS() TSRMLS_CC”生成;第二個參數(shù)是一個字符串,其中每個字母代表一個變量類型,我們只有一個字符串型變量,所以第二個參數(shù)是“s”;最后各個參數(shù)需要一些必要的局部變量指針用于存儲數(shù)據(jù),下表給出了不同變量類型的字母代表及其所需要的局部變量指針。

image

參數(shù)解析完成后就是核心功能代碼,我們這里只是輸出一行字符,php_printf是Zend版本的printf。

最后的返回值也是通過宏實現(xiàn)的。RETURN_TRUE宏是返回布爾值“true”。

使用宏ZEND_BEGIN_ARG_INFO和ZEND_END_ARG_INFO定義參數(shù)信息

參數(shù)信息是函數(shù)所必要部分,這里不做深究,直接給出相應(yīng)代碼:

  1. ZEND_BEGIN_ARG_INFO(arginfo_say_hello_func, 0)    
  2. ZEND_END_ARG_INFO()  

如需了解具體信息請閱讀相關(guān)宏定義。

使用宏P(guān)HP_FE將函數(shù)加入到say_hello_functions中

最后,我們需要將剛才定義的函數(shù)和參數(shù)信息加入到say_hello_functions數(shù)組里,代碼如下:

  1. const zend_function_entry say_hello_functions[] = {    
  2.      PHP_FE(say_hello_func, arginfo_say_hello_func)    
  3.     {NULL, NULL, NULL}    
  4. };  

這一步就是通過PHP_EF宏實現(xiàn),注意這個數(shù)組最后一行必須是{NULL, NULL, NULL} ,請不要刪除。

下面是編寫完成后的say_hello.c全部代碼:

  1.  /*    
  2.    +---------------------------------------------------------------------+    
  3. | PHP Version 5                                                        |    
  4.    +----------------------------------------------------------------------+    
  5.    | Copyright (c) 1997-2010 The PHP Group                                |    
  6.    +----------------------------------------------------------------------+    
  7.   | This source file is subject to version 3.01 of the PHP license,      |    
  8.  | that is bundled with this package in the file LICENSE, and is        |    
  9.   | available through the world-wide-web at the following url:           |    
  10.   | http://www.php.net/license/3_01.txt                                  |    
  11.   | If you did not receive a copy of the PHP license and are unable to   |    
  12.    | obtain it through the world-wide-web, please send a note to          |    
  13.    | license@php.net so we can mail you a copy immediately.               |    
  14.    +----------------------------------------------------------------------+    
  15.    | Author:                                                              |    
  16.   +----------------------------------------------------------------------+    
  17.  */   
  18.  /* $Id: header 297205 2010-03-30 21:09:07Z johannes $ */   
  19.  #ifdef HAVE_CONFIG_H    
  20. #include "config.h"    
  21.  #endif    
  22. #include "php.h"    
  23. #include "php_ini.h"    
  24.  #include "ext/standard/info.h"    
  25.  #include "php_say_hello.h"    
  26.  /* If you declare any globals in php_say_hello.h uncomment this:    
  27.  ZEND_DECLARE_MODULE_GLOBALS(say_hello)    
  28.  */   
  29.  /* True global resources - no need for thread safety here */   
  30. static int le_say_hello;    
  31.  /* {{{ PHP_FUNCTION    
  32.   */   
  33. PHP_FUNCTION(say_hello_func)    
  34.  {    
  35.      char *name;    
  36.      int name_len;    
  37.   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE)    
  38.    {    
  39.        return;    
  40.      }    
  41.     php_printf("Hello %s!", name);    
  42.    RETURN_TRUE;    
  43.  }    
  44. ZEND_BEGIN_ARG_INFO(arginfo_say_hello_func, 0)    
  45.  ZEND_END_ARG_INFO()    
  46.  /* }}} */   
  47.  /* {{{ say_hello_functions[]    
  48.   *    
  49.   * Every user visible function must have an entry in say_hello_functions[].    
  50.  */   
  51.  const zend_function_entry say_hello_functions[] = {    
  52.      PHP_FE(say_hello_func, arginfo_say_hello_func)    
  53.      {NULL, NULL, NULL}  /* Must be the last line in say_hello_functions[] */   
  54.  };    
  55.  /* }}} */   
  56. /* {{{ say_hello_module_entry    
  57.   */   
  58. zend_module_entry say_hello_module_entry = {    
  59.  #if ZEND_MODULE_API_NO >= 20010901    
  60.      STANDARD_MODULE_HEADER,    
  61.  #endif    
  62.     "say_hello",    
  63.     say_hello_functions,    
  64.     NULL,    
  65.     NULL,    
  66.      NULL,    
  67.      NULL,    
  68.     PHP_MINFO(say_hello),    
  69.  #if ZEND_MODULE_API_NO >= 20010901    
  70.     "0.1"/* Replace with version number for your extension */   
  71.  #endif    
  72.     STANDARD_MODULE_PROPERTIES    
  73.  };    
  74.  /* }}} */   
  75. #ifdef COMPILE_DL_SAY_HELLO    
  76.  ZEND_GET_MODULE(say_hello)    
  77. #endif    
  78.  /* {{{ PHP_MINFO_FUNCTION    
  79.   */   
  80. PHP_MINFO_FUNCTION(say_hello)    
  81.  {    
  82.      php_info_print_table_start();    
  83.      php_info_print_table_header(2, "say_hello support""enabled");    
  84.     php_info_print_table_row(2, "author""Zhang Yang"); /* Replace with your name */   
  85.    php_info_print_table_end();    
  86.     /* Remove comments if you have entries in php.ini    
  87.     DISPLAY_INI_ENTRIES();    
  88.    */   
  89. }    
  90.  /* }}} */  

編譯并安裝擴展

在say_hello目錄下輸入下面命令:

  1. /usr/bin/phpize    
  2. ./configure    
  3. make   
  4. make install  

這樣就完成了say_hello擴展的安裝(如果沒有報錯的話)。

這時如果你去放置php擴展的目錄下,會發(fā)現(xiàn)多了一個say_hello.so的文件。如下圖所示:

image

下面就是將其加入到php.ini配置中,然后重啟Apache(如果需要的話)。這些都是PHP基本配置的內(nèi)容,我就不詳述了。

擴展測試

如果上面順利完成,這時運行phpinfo(),應(yīng)該能看到如下信息:

image

這說明擴展已經(jīng)安裝成功了。然后我們編寫一個測試用PHP腳本:

  1. php    
  2.  say_hello_func('Zhang Yang');    
  3.  ?>  

執(zhí)行這個腳本,結(jié)果如下:

image說明擴展已經(jīng)正常工作了。

總結(jié)

這篇文章主要用示例方法介紹PHP Extension的開發(fā)基礎(chǔ)。在PHP的使用中,也許是因為需要支持新的組件(如新的數(shù)據(jù)庫),又或是業(yè)務(wù)需要或性能需要,幾乎都會遇到需要開發(fā)PHP擴展的地方。后續(xù)如果有機會,我會寫文章介紹一些關(guān)于擴展開發(fā)較為深入的東西,如擴展模塊生命周期、INI使用以及編寫面向?qū)ο蟮臄U展模塊等等。

原文鏈接:http://www.cnblogs.com/leoo2sk/archive/2010/12/09/talk-about-php-ext-develop-basic.html

【編輯推薦】

  1. 讓PHP開發(fā)者事半功倍的十大技巧
  2. PHP開發(fā)者不可不知的五件事
  3. 優(yōu)秀的PHP開發(fā)者是怎樣煉成的?
  4. 十款PHP開發(fā)者值得關(guān)注的編碼工具 

 

責任編輯:彭凡 來源: 博客園
相關(guān)推薦

2009-01-16 14:08:42

PHP開發(fā)Web應(yīng)用執(zhí)行效率

2011-09-22 15:15:40

2009-09-03 10:41:46

Windows Cac

2009-11-17 09:13:21

PHP運算符

2011-08-18 10:02:47

iPhone SDKOpenFlow

2011-08-18 09:52:13

iPhone SDKUIPageContr

2010-06-02 15:24:15

PHP+MySQL

2018-08-16 09:29:26

2009-03-23 10:53:00

PHP5.3新特性PHP5.3PHP5

2019-10-31 08:00:00

機器學習人工智能AI

2009-07-22 10:03:11

iBATIS Resu

2009-08-06 18:18:27

ASP.NET控件開發(fā)ASP.NET復合控件

2009-08-06 13:08:23

ASP.NET控件開發(fā)

2010-11-03 10:31:51

PHP魔術(shù)方法

2009-12-11 10:59:48

PHP函數(shù)extrac

2024-06-07 13:11:44

2023-04-07 09:20:55

2009-08-27 11:43:31

C#語法

2009-09-23 11:07:11

Hibernate基礎(chǔ)

2009-11-30 16:40:38

PHP object對
點贊
收藏

51CTO技術(shù)棧公眾號

成人av免费网站| 国产精品香蕉| 国产精品天美传媒沈樵| 91精品国产综合久久久久久蜜臀| 99久久99久久精品国产| xxxx日韩| 91福利区一区二区三区| 在线观看欧美亚洲| 中文字幕在线看高清电影| 91精品久久久久久粉嫩| 欧美r级在线| 国产精品久久久久久久精| 国产精品美女久久久久人| 亚洲成人精品在线观看| 五月天婷亚洲天综合网鲁鲁鲁| 怡春院在线视频| 国产一区清纯| 日韩午夜在线视频| av在线三区| 91亚洲国产| 欧美不卡在线视频| 欧美黄色一级片视频| 黄色动漫在线观看| 久久免费国产精品| 99r国产精品视频| 欧美国产一级片| 开心激情综合| 欧美一级黄色大片| 午夜免费看视频| 成人性生交大片免费观看网站| 亚洲乱码精品一二三四区日韩在线| 欧美二区三区在线| 色窝窝无码一区二区三区成人网站 | 国产精品19乱码一区二区三区| 2021亚洲天堂| 午夜亚洲国产au精品一区二区| 国产欧美日韩中文字幕| av大片免费在线观看| 我不卡神马影院| 中文字幕欧美日韩| 一区二区三区久久久久| 日韩大胆成人| 亚洲成人av中文字幕| 亚洲高清av一区二区三区| 欧美成人精品三级网站| 一道本成人在线| 男人天堂1024| 热三久草你在线| 欧美日韩国产专区| 国产午夜福利在线播放| 久草在线资源站资源站| 依依成人精品视频| www.日本三级| caoprom在线| 亚洲国产日日夜夜| 妞干网在线视频观看| 草莓视频丝瓜在线观看丝瓜18| 亚洲欧美日韩综合aⅴ视频| 三年中文高清在线观看第6集| √天堂资源地址在线官网| 国产清纯在线一区二区www| 日韩精品欧美专区| av在线电影院| 亚洲三级在线免费| 成人免费在线观看入口| 91免费的视频在线播放| 国产青青草视频| 国产v日产∨综合v精品视频| 成人国产1314www色视频| 亚洲老妇色熟女老太| 成人性生交大合| 国产精品区一区二区三含羞草| 蜜臀av午夜精品| 91色婷婷久久久久合中文| 久久99蜜桃综合影院免费观看| 国产精品久久久久久麻豆一区软件| 91久久香蕉国产日韩欧美9色| 国产精品欧美激情在线观看| 激情开心成人网| 欧美色偷偷大香| 天天干天天曰天天操| 亚洲日本视频在线| 日韩av网站在线| 日韩av片在线| 欧美日韩视频一区二区三区| 欧美在线一区二区视频| 青青艹在线观看| 国产精品一二三四| 国产一区自拍视频| av免费观看一区二区| 亚洲免费av观看| 黄色动漫在线免费看| 日本电影久久久| 日韩毛片在线看| 开心激情五月网| 国产精品久久777777毛茸茸| 欧美剧在线免费观看网站 | 免费一级毛片在线观看| 国产精品视频yy9299一区| 男女啪啪的视频| 中国色在线日|韩| 69精品人人人人| 成年人在线观看av| 亚洲情侣在线| 国产成人欧美在线观看| 精品久久久中文字幕人妻| 久久先锋影音av鲁色资源| 一区二区三区四区免费观看| 小早川怜子影音先锋在线观看| 欧美精品v国产精品v日韩精品| www.男人天堂| 久久久久久久久久久9不雅视频| 久久久久久久久久国产精品| 久久精品偷拍视频| 高清久久久久久| 亚洲欧美日本国产有色| 不卡视频观看| 日韩一级高清毛片| av电影在线不卡| 在线日韩av| 91久久精品国产91性色| 黄色国产在线| 欧美日韩国产一区在线| 国产精品无码自拍| 日韩成人a**站| 日本中文字幕久久看| 蜜臀av中文字幕| 亚洲九九爱视频| 亚洲美女性囗交| 欧美三级伦理在线| 99国内精品| 国产区精品视频| 国产福利在线| 欧美午夜精品久久久久久浪潮| 色欲欲www成人网站| 国产韩日影视精品| 国产精品美女久久| 国产三级在线免费| 色婷婷亚洲综合| 国产精品揄拍100视频| 99精品热6080yy久久| 电影午夜精品一区二区三区| www在线免费观看视频| 欧美日韩国产美女| 国产jk精品白丝av在线观看| 久久久www| 日本成人三级电影网站| 中文在线资源| 亚洲欧美日韩久久久久久| 天天综合网久久综合网| 日韩成人在线视频| 欧美一区二区中文字幕| 精品91福利视频| 久久精品视频播放| 在线视频免费观看一区| 欧美激情综合五月色丁香| 成人免费xxxxx在线视频| 免费一区二区三区视频导航| 日韩免费观看视频| 国产永久av在线| 黑人巨大精品欧美一区免费视频 | 韩国精品免费视频| 樱空桃在线播放| 久久免费福利| 国语自产精品视频在免费| 神马久久久久久久久久| 婷婷成人综合网| 免费观看av网站| 麻豆专区一区二区三区四区五区| 亚洲一区精彩视频| 日韩中文字幕一区二区高清99| 精品国产导航| 亚洲天堂成人在线| 中文字幕 国产| 亚洲人成人一区二区在线观看| 欧美午夜精品理论片| 欧美激情91| 久久精品午夜一区二区福利| 日韩精选视频| 欧美xxxx做受欧美| 日韩中文字幕免费观看| 日韩欧美有码在线| 成人性视频免费看| 成人永久免费视频| 成人精品视频一区二区| 婷婷六月综合| 国产精品久久一区二区三区| 欧美黑人粗大| 欧美成人免费观看| 久久精品蜜桃| 91精品欧美一区二区三区综合在| 免费麻豆国产一区二区三区四区| 99久久婷婷国产精品综合| 男女男精品视频站| 综合天天久久| 奇米影视首页 狠狠色丁香婷婷久久综合| 五月激情久久| 久久全国免费视频| 自拍视频在线网| 亚洲精品国产精品自产a区红杏吧| 久久久久在线视频| 一区二区三区精品在线观看| 色婷婷在线影院| 国产不卡在线播放| 日本xxxx黄色| 99精品国产一区二区青青牛奶| 国产香蕉精品视频一区二区三区| 免费看日本毛片| 国产一区二区三区四区五区| 亚洲影院色无极综合| 黑人巨大精品欧美一区二区桃花岛| 久久天天躁夜夜躁狠狠躁2022| 婷婷亚洲一区二区三区| 正在播放亚洲一区| 草莓视频18免费观看| 亚洲在线观看免费| 国产午夜精品久久久久久久久| 成人黄色777网| 在线看免费毛片| 性欧美暴力猛交另类hd| 黄色一级大片免费| 99re6这里只有精品| 久久国产欧美精品| 亚洲精品a区| 成人免费视频97| 欧美精品资源| 日韩av电影在线网| heyzo一区| 欧美激情2020午夜免费观看| 日本高清视频在线播放| 尤物yw午夜国产精品视频明星 | 日本少妇一区| 热久久免费视频精品| 爱啪视频在线观看视频免费| 欧美国产在线视频| 少妇视频在线观看| 亚洲国产天堂久久综合网| 888奇米影视| 91久久精品午夜一区二区| 日本在线免费观看| 亚洲午夜在线观看视频在线| 国产精品国产三级国产传播| 91嫩草精品| 欧美午夜性色大片在线观看| 久草免费在线视频观看| 亚洲三级在线观看| 中日韩一级黄色片| 国产精品国产自产拍在线| 欧美老女人性生活视频| 欧美高清在线精品一区| 在线观看免费小视频| 国产亚洲一区二区三区四区| 蜜桃无码一区二区三区| 国产欧美一区二区精品性| 国产高潮呻吟久久| 欧美国产激情一区二区三区蜜月| 人妻少妇无码精品视频区| 国产亚洲一区二区三区| 欧美成人短视频| 最新高清无码专区| 91视频青青草| 一个色综合av| www.av麻豆| 91福利在线免费观看| а中文在线天堂| 欧美精品一级二级| www.com欧美| 亚洲精品美女免费| 邻家有女韩剧在线观看国语| 国产一区二区三区在线观看网站| 大乳在线免费观看| www.日韩.com| 五月花成人网| 欧美一区二区三区精品电影| 日韩精品影院| 亚洲在线免费看| 国产伦精品一区二区三区免费优势 | av大片在线免费观看| 色婷婷久久综合| 亚洲视频在线观看免费视频| 成人黄色在线网站| 欧美国产日韩精品| 26uuu亚洲电影在线观看| 欧美激情第一页xxx| 日韩av一卡| 国产精品直播网红| 99精品国产一区二区三区2021 | 九色精品91| 亚洲精品久久区二区三区蜜桃臀| 在线成人超碰| 久久无码高潮喷水| 韩国一区二区三区| 最近日本中文字幕| 国产精品视频第一区| 国产在线视频第一页| 日本韩国欧美一区| 99精品视频在线播放免费| 国产视频在线一区二区| 超碰在线网址| 日韩免费av一区二区| 蜜桃在线一区| 人禽交欧美网站免费| 欧美成熟视频| 日韩av手机版| 成人h动漫精品一区二区| www亚洲色图| 黄色91在线观看| www.av日韩| 中文字幕久热精品在线视频| 91破解版在线观看| 成人综合国产精品| 欧美一二区在线观看| 一卡二卡三卡视频| 久久精品国产77777蜜臀| 中文字幕丰满孑伦无码专区| 亚洲女人****多毛耸耸8| 蜜臀尤物一区二区三区直播| 亚洲国产精品视频在线观看| 国产黄a三级三级三级av在线看 | 丁香色欲久久久久久综合网| 日韩高清一级片| 真人bbbbbbbbb毛片| 亚洲综合视频在线| 91精品国产乱码久久| 国产亚洲欧美日韩美女| 麻豆网站免费在线观看| 高清视频一区| 中文字幕一区二区三区欧美日韩| 天天爽天天爽夜夜爽| 91女人视频在线观看| 日本少妇全体裸体洗澡| 日韩精品中文字幕在线一区| 黄色网在线免费看| 国产精品免费在线免费| 蜜桃tv一区二区三区| 国产黄色一级网站| av不卡在线播放| 日本免费在线播放| 日韩女优电影在线观看| 国产网友自拍视频导航网站在线观看 | 九九热精品在线观看| 一道在线中文一区二区三区| 91久久精品美女高潮| 欧美a级片视频| 欧美大尺度做爰床戏| 国产视频一区不卡| 国产第一页在线观看| 亚洲日韩欧美视频一区| 成人性生活视频| 欧美日韩综合另类| 久久高清一区| 日本性高潮视频| 在线一区二区三区做爰视频网站| 国产毛片av在线| 国产成人久久久精品一区| 国产日韩视频在线| 国产a级片免费观看| 中文字幕精品三区| 亚洲精品国产精品国自产网站按摩| 一区二区三区回区在观看免费视频| 国产综合av| 亚洲永久激情精品| 极品少妇xxxx精品少妇| 99鲁鲁精品一区二区三区| 91精品国产综合久久久久久久久久| 菠萝菠萝蜜在线观看| 动漫3d精品一区二区三区 | 久久久精品欧美| 三级欧美日韩| 91国视频在线| 国产性色一区二区| 91片黄在线观看喷潮| 色综合男人天堂| 老牛国内精品亚洲成av人片| 超碰影院在线观看| 欧美国产成人精品| www香蕉视频| 91精品国产一区| av中文字幕一区二区| 不卡的一区二区| 天天做天天摸天天爽国产一区| 国产永久av在线| 欧美在线免费观看亚洲| 91高清免费视频| 精品无人区一区二区| 白嫩少妇丰满一区二区| 国产精品国产馆在线真实露脸| www.国产免费| 欧美最顶级丰满的aⅴ艳星| 成人看的视频| 激情av中文字幕| 91国偷自产一区二区三区成为亚洲经典 | 精品在线欧美视频| 成人在线观看免费播放| 奇米777四色影视在线看| 久久天天做天天爱综合色| 国产人妖一区二区| 欧美一级视频在线观看| 欧美暴力喷水在线| 亚洲专区区免费|