精品欧美一区二区三区在线观看 _久久久久国色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ù)棧公眾號

aaa在线播放视频| 99国产成人精品| 亚洲自拍电影| 欧美亚洲尤物久久| 亚洲最新免费视频| www.激情五月| 久久xxxx精品视频| 色伦专区97中文字幕| 4438x全国最大成人| 天堂网在线最新版www中文网| 国产免费观看久久| 成人18视频| 国产精品免费无遮挡无码永久视频| 99久久国产综合精品成人影院| 日韩欧美亚洲国产精品字幕久久久| 一女被多男玩喷潮视频| 日韩在线观看www| av一本久道久久综合久久鬼色| 国产精品黄页免费高清在线观看| 欧美日韩亚洲国产另类| 精品毛片免费观看| 亚洲成人亚洲激情| 亚洲欧美偷拍另类| 在线最新版中文在线| 亚洲欧美另类久久久精品| 欧美激情第六页| 亚洲精品一区二区三区区别| 日本视频中文字幕一区二区三区| 欧美黑人极品猛少妇色xxxxx| 国产91丝袜美女在线播放| 风间由美一区二区av101| 欧美中文一区二区三区| 青青青国产在线观看| 国产成人高清精品| 中文在线一区二区| 免费看成人片| 神马午夜电影一区二区三区在线观看| 精品一区二区成人精品| 国产成人精品久久久| 日本少妇裸体做爰| 欧美久久九九| 欧美成人激情视频| 亚洲欧洲综合网| 欧美精品尤物在线观看| 亚洲欧洲偷拍精品| 日韩网站在线播放| 欧美巨大xxxx| 亚洲а∨天堂久久精品9966| 一级黄色大片儿| 精品国产伦一区二区三区观看说明 | 国产在线a不卡| 综合久久中文字幕| 日韩一区精品视频| 国产精品99久久久久久www| 天堂在线免费观看视频| 亚洲美女毛片| 国语自产精品视频在免费| 男女免费视频网站| 亚洲天堂激情| 国内精品伊人久久| 在线观看免费国产视频| 国产精品久久久亚洲一区| 韩日欧美一区二区| 日韩精品一区二区av| 国产欧美日本| 欧美一级淫片丝袜脚交| 在线能看的av| 日日摸夜夜添夜夜添精品视频| 日本久久久久亚洲中字幕| 中文字幕一区二区人妻电影| 久久天堂精品| 国产女人精品视频| 国产乱子伦精品无码码专区| 精品午夜久久福利影院| 1卡2卡3卡精品视频| 精品人妻午夜一区二区三区四区| 国产91精品入口| 国产欧美日韩视频一区二区三区| 午夜黄色小视频| 国产色婷婷亚洲99精品小说| 亚洲五月六月| 日本资源在线| 欧美视频中文字幕在线| 天天操天天爱天天爽| 成人永久在线| 亚洲精品久久久久久久久久久久| 久久精品国产亚洲AV熟女| 亚洲大尺度网站| 国产黑丝在线一区二区三区| 亚洲一区二区在线播放| 亚洲黄色一级大片| 久久免费美女视频| 成年人免费观看的视频| 丁香花在线电影| 91成人网在线| 免费看涩涩视频| 三上悠亚亚洲一区| 91精品中文字幕一区二区三区 | 成人午夜av在线| 九九九九九九精品| 在线激情免费视频| 亚洲一区二区三区小说| 亚洲乱码国产一区三区| 99精品视频在线免费播放| 精品久久久久久久一区二区蜜臀| 给我看免费高清在线观看| 欧美韩国日本在线观看| 97精品视频在线播放| 欧美性受xxx黑人xyx性爽| 国产成人综合网| 欧美精品一区二区三区四区五区| 久草中文在线| 色88888久久久久久影院按摩| xxx中文字幕| 国产最新精品| 韩国日本不卡在线| 国产又粗又猛又爽又黄的视频一 | 男女在线视频| 欧美在线免费观看视频| 最新中文字幕日本| 日韩欧美午夜| 欧美在线视频免费观看| 性做久久久久久久| 国产精品理论在线观看| 青青草原av在线播放| 亚洲精品一区二区三区在线| 中文字幕国内精品| 日韩精品在线观看免费| 国产馆精品极品| 日韩视频在线免费播放| 日韩高清不卡| 亚洲视频axxx| 亚洲天堂一区在线| 99综合电影在线视频| 中国一级黄色录像| 黄色精品视频网站| 在线视频精品一| 欧美男人亚洲天堂| 99精品视频在线观看免费| 国产资源第一页| 国产精品va视频| www.日韩免费| 在线免费观看一区二区| 国产婷婷色一区二区三区在线| 国产精品久久..4399| 国产一区二区视频在线看| 最近中文字幕mv在线一区二区三区四区 | 蜜桃91麻豆精品一二三区| 亚洲三级免费观看| 8x8x成人免费视频| 99久久www免费| 成人激情视频小说免费下载| 色老头视频在线观看| 欧美三区在线视频| 黄色国产在线播放| 美女精品自拍一二三四| 亚洲一卡二卡三卡四卡无卡网站在线看| 欧美gay囗交囗交| 亚洲欧美制服中文字幕| 久久久蜜桃一区二区| 久久精品视频网| 狠狠热免费视频| 日韩精品第一区| 国产欧美va欧美va香蕉在线| 成人在线直播| 日韩欧美国产成人一区二区| 国产一级黄色av| 成人精品小蝌蚪| 91视频 -- 69xx| 精品在线播放| 国产视频观看一区| 影音先锋在线播放| 亚洲国产日韩欧美综合久久 | 欧美日韩一区二区三区免费看| 欧美人妻一区二区三区| 麻豆精品一区二区av白丝在线| 三年中文高清在线观看第6集| 欧美中文高清| 性色av一区二区三区免费| 男男电影完整版在线观看| 欧美图区在线视频| 国产高潮国产高潮久久久91| 成人av一区二区三区| 日韩中文字幕二区| 香蕉综合视频| 精品中文字幕一区| 国产精品蜜月aⅴ在线| 美女少妇精品视频| 亚洲欧洲国产综合| 欧美精品1区2区| 日韩欧美a级片| 综合欧美一区二区三区| 日本道中文字幕| 免费人成精品欧美精品| 麻豆传媒网站在线观看| 在线日韩一区| 亚洲一区久久久| 澳门成人av网| 九九热精品视频国产| 精品推荐蜜桃传媒| 精品免费视频一区二区| 亚洲性在线观看| 精品美女久久久久久免费| 91av手机在线| 91色在线porny| 最好看的中文字幕| 日本成人中文字幕在线视频| 欧美乱大交xxxxx潮喷l头像| 91免费精品| 欧美精品成人一区二区在线观看 | 国产毛片精品视频| 日韩在线第三页| aa级大片欧美三级| 中文字幕日韩精品无码内射| 欧美精品一区二区三区中文字幕 | 日韩欧美视频| 欧美视频1区| 群体交乱之放荡娇妻一区二区 | 日韩啪啪网站| 成人羞羞视频免费| 国产精品久久久久久av公交车 | 日韩精品亚洲专区在线观看| 国产精品高潮呻吟久久av野狼 | 国产区精品在线观看| 国产www视频在线观看| 最新的欧美黄色| 五月激情婷婷网| 欧美电影免费观看完整版| 欧美国产一级片| 欧美日韩色婷婷| 国产精品成人免费一区二区视频| 国产精品人妖ts系列视频| 88av在线播放| 成人h精品动漫一区二区三区| 色天使在线观看| 老鸭窝亚洲一区二区三区| 日本男女交配视频| 国模吧视频一区| 日韩视频在线免费播放| 精品黄色一级片| 日韩欧美在线电影| 青青视频一区二区| 国产成人免费观看| 一个人看的www视频在线免费观看| 久久青草福利网站| 怡红院av在线| 欧美激情精品久久久久久蜜臀| 黄色网页在线免费看| 国产一区二区三区视频在线观看| 成人午夜视频一区二区播放| 精品奇米国产一区二区三区| 国产欧美熟妇另类久久久| 欧美日韩国产一二三| 亚洲天堂网在线观看视频| 欧美综合天天夜夜久久| 色屁屁影院www国产高清麻豆| 色诱亚洲精品久久久久久| 国产成人无码精品久在线观看| 一区二区三区欧美日| 日本中文字幕免费在线观看| 亚洲精品久久久久久国产精华液| 成人涩涩小片视频日本| 自拍视频在线观看一区二区| 私库av在线播放| 亚洲一区二区三区视频在线播放| 欧美国产精品一二三| 婷婷一区二区三区| 欧美一区二区三区四| 大荫蒂欧美视频另类xxxx| 欧美三级韩国三级日本三斤在线观看| 欧美视频在线视频| 天天干天天操天天爱| 91国偷自产一区二区三区成为亚洲经典| 欧美性受xxx黑人xyx性爽| 欧美日韩国产综合一区二区| 亚洲一区二区天堂| 日韩女同互慰一区二区| 黄色成人一级片| 日韩精品在线观看一区| 婷婷国产在线| 日韩在线国产精品| www免费视频观看在线| 久久久久久av| 日本一区二区三区视频在线| 国产专区精品视频| 日本精品一区二区三区在线观看视频| 国产亚洲情侣一区二区无| 夜夜春成人影院| 天天好比中文综合网| 欧美精品观看| 国产网站免费在线观看| 日一区二区三区| 日本中文字幕在线不卡| 91丨porny丨最新| 欧美巨胸大乳hitomi| 亚洲精品久久久久久国产精华液| 伊人手机在线视频| 欧美日韩一区二区三区在线 | 日本一区精品| 中文字幕一区二区av| 久艹视频在线免费观看| 日本不卡一区二区| 亚洲欧美日韩中文字幕在线观看| www.欧美.com| 久久久久久国产免费a片| 亚洲黄色尤物视频| 中文字幕在线欧美| 精品国产一区a| av福利精品| 久久久久久九九九| www999久久| 欧美日韩三区四区| 999成人精品视频线3| 僵尸世界大战2 在线播放| 免播放器亚洲一区| 中文字幕 欧美日韩| 国产丝袜欧美中文另类| 九九热精品在线观看| 黑人巨大精品欧美一区二区| 国产高清第一页| 在线a欧美视频| 国产极品人妖在线观看| 国产精品一区二区三区免费视频| 大桥未久女教师av一区二区| 亚洲国产另类久久久精品极度| 亚洲精品国产成人影院| 久久精品无码中文字幕| 久久国产精品第一页| 黑丝av在线播放| 亚洲高清免费观看高清完整版在线观看| 天天爱天天做天天爽| 亚洲第一免费网站| 丁香花高清在线观看完整版| 成人久久久久久| 精品72久久久久中文字幕| 91视频最新入口| 粉嫩一区二区三区性色av| 免费看一级黄色| 欧美日韩成人综合在线一区二区| 日本中文字幕一区二区有码在线 | 美女诱惑黄网站一区| 一级欧美一级日韩片| 一区二区三区不卡视频| 97人妻一区二区精品免费视频| 亚洲网站在线播放| 日本不卡一二三| 日韩中文一区| 久久久综合网| 中国毛片在线观看| 欧美自拍丝袜亚洲| 国产经典自拍视频在线观看| 性欧美xxxx视频在线观看| 天海翼亚洲一区二区三区| 丰满的少妇愉情hd高清果冻传媒 | 欧美又大又粗又长| 日本中文字幕在线一区| 国产aaa免费视频| 2021中文字幕一区亚洲| 午夜影院在线看| 日韩精品高清在线| 韩日精品一区| 日韩偷拍一区二区| 日韩电影一二三区| 五月天婷婷色综合| 欧美一二三四在线| 欧洲一区精品| 美乳视频一区二区| 久久xxxx| 爱爱视频免费在线观看| 制服.丝袜.亚洲.另类.中文 | 午夜精品久久久久久久男人的天堂 | 亚洲最大色网站| 刘亦菲久久免费一区二区| 欧美巨大黑人极品精男| 国产精品中文字幕制服诱惑| 六月婷婷在线视频| 欧美国产1区2区| 国产一区二区三区在线观看| 久久久久999| 欧美三级午夜理伦三级小说| 99福利在线观看| 国产视频一区二区在线| 国产成a人亚洲精v品无码| 欧美激情精品久久久| 精品国产一区二区三区小蝌蚪| 在线看的黄色网址| 亚洲精品免费播放| 欧美女同网站| 91精品国产综合久久香蕉最新版 | 800av在线免费观看| 久久免费视频色| 国产精品人人妻人人爽| 欧美人与物videos| 欧美日韩激情| 少妇性l交大片7724com| 狠狠操狠狠色综合网| 91在线不卡| 国产精品国产精品国产专区不卡| 日本vs亚洲vs韩国一区三区二区| 国产免费美女视频|