亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > PHP > 正文

PHP擴展開發入門教程

2024-05-04 23:31:39
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了PHP擴展開發入門教程,本文講解了使用C語言在Linux系統下開發一個PHP擴展應該具備的最基本知識,需要的朋友可以參考下
 

PHP擴展開發

我準備在此系列博文中總結我有關PHP擴展開發的學習和感悟,力圖簡單清晰地描述在Linux系統下開發一個PHP擴展應該具備的最基本知識。水平較低,難免有錯誤,望指出。

準備工作

首先要獲取一份PHP源碼(可以從Github上簽出,或者到官網上下載最新的穩定版),然后編譯之。為了加快編譯速度,我們推薦禁用所有額外的擴展(使用--disable-all選項),但最好打開debug(使用--enable-debug選項)和線程安全(使用--enable-maintainer-zts),但要在發布擴展的時候關閉debug,視情況選擇是否需要打開線程安全:

復制代碼代碼如下:

$ ./buildconf --force
$ ./configure --disable-all --enable-debug --enable-maintainer-zts
$ make

注意,我們沒有指定--prefix選項(同時也沒有make install),因為這不是必須的。注意查看輸出信息,也許你需要安裝一些依賴包才能成功編譯PHP。

 

編譯后的PHP的可執行程序在源碼的sapi目錄下,對應不同的宿主環境有不同的子目錄,我們以后都主要使用cli(command line interface)環境,可以建一個別名方便引用:

復制代碼代碼如下:

$ alias php-dev=/usr/local/src/php-5.6.5/sapi/cli/php

 

有一些命令行選項是很有用的:

復制代碼代碼如下:

php-dev -h          # 打印幫助信息
php-dev -v          # 打印版本信息
php-dev --ini        # 打印配置信息        
php-dev -m          # 打印加載的模塊信息
php-dev -i          # phpinfo
php-dev -r <code>      # 執行code里的代碼

 

擴展骨架

PHP的所有官方擴展都在源碼的ext目錄下,我們自己寫的擴展也可以放在該目錄下。注意,該目錄下有個名為ext_skel的shell腳本,它是用來生成PHP擴展骨架的,使用該腳本,可以幫我們快速創建PHP擴展:

復制代碼代碼如下:

$ ./ext_skel --extname=myext

上面的命令幫我們創建了一個名為myext的擴展,源碼在myext目錄下。不帶任何參數的執行該腳本可以打印幫助信息,這樣你可以查看到該腳本提供的更多選項。

 

接下來讓我們完成我們的擴展。進入myext目錄,編輯config.m4配置文件,找到PHP_ARG_ENABLE宏函數,去掉前面的dnl注釋(共三行)。退回到源碼根目錄,重新執行buildconf、configure和make命令:

復制代碼代碼如下:

$ ./buildconf --force
$ ./configure --help | grep myext
    --enable-myext           Enable myext support
$ ./configure --disable-all --enable-myext --enable-debug --enable-maintainer-zts
$ make

 

注意,我們用./configure --help | grep myext打印了我們擴展的加載情況,如果看不到下面的輸出,則說明我們的擴展沒有配置成功,回頭檢查下config.m4文件。

這次編譯應該非??欤驗榇蟛糠执a都已經編譯過了。PHP還有另外一種編譯擴展的方法(使用動態連接的方式,將擴展編譯為.so的文件),不過我們推薦在開發擴展的時候使用靜態編譯,因為這樣省去了在配置文件中加載擴展的步驟。

一切順利的話,我們的第一個擴展就已經可以執行了:

復制代碼代碼如下:

$ php-dev -m | grep myext
myext
$ php-dev -r 'echo confirm_myext_compiled("myext") . "/n";'
Congratulations! You have successfully modified ext/myext/config.m4. Module myext is now compiled into PHP.

第一個命令顯示了我們的擴展已經被加載。第二個命令執行了ext_skel擴展骨架自動為我們創建的函數。當然,這個函數毫無意義,不過我們可以很容易的把這個函數改編成hello world。

 

手動創建擴展

大部分教程都是以ext_skel擴展骨架為原型講述擴展開發的,這種做法當然很方便快捷。但是我個人更喜歡純手工開發擴展的方式,因為這樣更容易理解其中的每一個細節。

手動創建擴展,先進入ext目錄,創建我們的擴展目錄myext2。有幾個文件是必須的:config.m4,myext2.c和php_myext2.h。

首先,我們來編寫配置文件config.m4:

復制代碼代碼如下:

PHP_ARG_ENABLE(myext2, whether to enable myext2 support,
[  --enable-myext2           Enable myext2 support])

 

if test "PHP_MYEXT2" != "no"; then
   PHP_NEW_EXTENSION(myext2, myext2.c, $ext_shared)
fi


config.m4其實是autoconf程序使用的配置文件,autoconf是autotools工具箱里重要的組成。完整介紹autoconf的用法是需要很長時間的,好在我們這里的用法非常簡單。

 

PHP_ARG_ENABLE是PHP為autoconf定義的宏函數,myext2是它的第一個參數,指出了擴展的名字;后面兩個參數只是在make和configure執行時用來顯示的,所以我們可以隨便寫。[ ]在autoconf語法中的作用類似于雙引號,用來包裹字符串(注意第二個參數中包含了空格,但是可以不用方括號起來)。還有第四個參數用來指明擴展默認是開啟還是關閉(yes或no),默認是no。

下面三行其實就是shell語法,判斷我們是否開啟了PHP_MYEXT2擴展模塊。如果開啟了該擴展模塊(--enable-myext2),則$PHP_MYEXT2變量的值不為no,因此執行PHP_NEW_EXTENSION宏。這個宏函數也是PHP為autoconf定義的擴展語法,第一個參數同樣是擴展名稱;第二個參數是擴展要編譯的C文件,如果有多個,依次寫下去就可以了(空格分隔);第三個參數固定是$ext_shared。

接下來編寫php_myext2.h頭文件,該文件的命名是PHP擴展的規范 — php_擴展名.h:

復制代碼代碼如下:

#ifndef PHP_MYEXT2_H
#define PHP_MYEXT2_H

 

extern zend_module_entry myext2_module_entry;
#define phpext_myext2_ptr &myext2_module_entry

#define PHP_MYEXT2_VERSION "0.1.0"

/* prototypes */
PHP_FUNCTION(hello);

#endif  /* PHP_MYEXT2_H */

 

這里主要的代碼是定義了名為phpext_myext2_ptr的宏,PHP底層通過該宏來引用我們的擴展??梢钥闯觯摵甑拿瑯邮怯幸幏兜?— phpext_擴展名_ptr。而myext2_module_entry是我們稍后要在.c文件里定義的結構體,它的命名也是規范的 — 擴展名_module_entry。

此外我們還定義了一個標識我們擴展版本號的宏和一個函數原型(通過PHP_FUNCTION宏,PHP_FUNCTION宏函數的參數是外部可使用的函數名),稍后我們會來實現這個函數。

最后來看下myext2.c文件的實現:

復制代碼代碼如下:

#include "php.h"
#include "php_myext2.h"

 

/* {{{ myext2_functions[]
 *
 * Every user visible function must have an entry in myext2_functions[].
 */
static const zend_function_entry myext2_functions[] = {
    PHP_FE(hello,       NULL)
    PHP_FE_END
};
/* }}} */

/* {{{ myext2_module_entry
 */
zend_module_entry myext2_module_entry = {
    STANDARD_MODULE_HEADER,
    "myext2",               /* module name */
    myext2_functions,       /* module functions */
    NULL,                   /* module initialize */
    NULL,                   /* module shutdown */
    NULL,                   /* request initialize */
    NULL,                   /* request shutdown */
    NULL,                   /* phpinfo */
    PHP_MYEXT2_VERSION,     /* module version */
    STANDARD_MODULE_PROPERTIES
};
/* }}} */

#ifdef COMPILE_DL_MYEXT2
ZEND_GET_MODULE(myext2)
#endif

/* {{{ proto void hello()
   Print "hello world!" */
PHP_FUNCTION(hello)
{
    php_printf("hello world!/n");
}
/* }}} */

 

對比下擴展骨架創建的.c文件就會發現,我們的.c文件非常的簡單,其實這些對一個最基本的擴展來說就已經足夠了。

上面的代碼是簡單而清晰的,大部分注釋已經很具說明性了。我們再簡要概括下:

1.開頭包含我們要用到的頭文件。php.h是必須的,它已經幫我們包含了我們會用到的絕大多數的標準庫文件,比如stdio.h,stdlib.h等等。
2.myext2_functions定義了由我們要暴露出去的函數構成的結構體數組,每一個元素通過PHP_FE宏來指定。PHP_FE宏有兩個參數,第一個是外部可使用的函數名,第二個是參數信息(這里我們簡單使用了NULL),最后一個元素必須是PHP_FE_END。注意它的注釋,再次強調,每一個要暴露給外部使用的函數,都必須在該結構體數組中有定義。
3.myext2_module_entry定義了我們的模塊信息,它是一個結構體,大部分屬性都已經通過注釋給出了說明。注意中間的五個函數指針,我們都簡單的置為了NULL,在后續的博文中會講述它們的用法。
4.ZEND_GET_MODULE(myext2)宏函數是被ifdef宏包含的,所以說它是否調用是視情況而定的。至于什么情況下會被調用,什么情況下不會被調用,在后續的博文中會講述。
5.最后幾行代碼我們實現了hello函數,它很簡單,調用php_printf輸出hello world!跟一個換行符,php_printf的用法和printf完全一樣。
6.注釋里的 {{{ 和 }}} 是為了方便vim等編輯器折疊而使用的,我們推薦你也這樣來寫注釋。
這里面涉及了一些宏,比如PHP_FE,PHP_FE_END,PHP_FUNCTION等等,完整介紹這些宏要到后續的博文中才可以,眼下最簡單的辦法就是記住這些宏。

注意到我們每一個文件的命名,變量的命名,空格和縮進,以及注釋等都是非常規范的,遵循這些規范,可以使我們編寫的代碼和PHP本身的代碼更加契合,我們也推薦你使用這樣的規范來開發PHP擴展。

最后,編譯運行我們的擴展:

復制代碼代碼如下:

$ ./buildconf --force
$ ./configure --help | grep myext2
  --enable-myext2           Enable myext2 support
$ ./configure --disable-all --enable-myext2 --enable-debug --enable-maintainer-zts
$ make

 

$ php-dev -m | grep myext2
myext2
$ php-dev -r 'hello();'
hello world!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
97视频在线观看免费高清完整版在线观看| 亚洲色图偷窥自拍| 精品久久久久久亚洲国产300| 日韩av电影手机在线观看| 久久视频在线播放| 国产精品视频久久| 成人黄色中文字幕| 久久久噜噜噜久噜久久| 亚洲成人av在线| 91精品视频一区| 国产一区二区久久精品| 欧美精品18videosex性欧美| 97国产精品视频人人做人人爱| 日韩美女在线观看一区| 亚洲国产精品久久久久秋霞蜜臀| 精品久久久久久久久久国产| 91精品国产高清久久久久久久久| 中文字幕成人在线| 亚洲国产精品va在线看黑人动漫| 亚洲欧美日韩国产中文| 欧美在线亚洲在线| 欧美黑人xxxⅹ高潮交| 国产精品久久77777| 日韩av免费网站| 欧美区在线播放| 91九色精品视频| 成人免费看黄网站| 97久久精品人搡人人玩| 久久久久中文字幕2018| 国产精品99久久久久久白浆小说| 亚洲韩国青草视频| 一区二区欧美久久| 国产精品色婷婷视频| 91丨九色丨国产在线| 欧美日本在线视频中文字字幕| 国产丝袜一区二区三区免费视频| 欧美精品在线极品| 欧美插天视频在线播放| 亚洲国产精品成人av| 黑人狂躁日本妞一区二区三区| 国产欧美 在线欧美| 91精品久久久久久久久| 91av视频在线免费观看| 成人a免费视频| 欧美一级成年大片在线观看| 日韩中文在线视频| 国产婷婷成人久久av免费高清| 欧美在线观看网址综合| 欧美成人免费全部| 国产精品久久久久7777婷婷| 精品电影在线观看| 欧美性极品xxxx做受| 国产精品视频大全| 国产成人久久久精品一区| 精品毛片三在线观看| 久久精品中文字幕一区| 日韩av在线免费看| 91成人国产在线观看| 伊人久久精品视频| 亚洲欧美在线看| 啊v视频在线一区二区三区| 欧美在线视频在线播放完整版免费观看| 91久久久久久久久久| 国产精品视频免费在线| 亚洲精品天天看| 国产日韩欧美日韩大片| 成人黄色影片在线| 精品国产成人av| 久久人人爽人人爽人人片av高请| 日本久久久久亚洲中字幕| 欧美性色xo影院| 4444欧美成人kkkk| 久久久精品电影| 国产精品亚洲综合天堂夜夜| 久久久久久91| 成人黄色在线免费| 欧美激情久久久久| 亚洲国产精品va在线看黑人动漫| 91干在线观看| 亚洲午夜女主播在线直播| 国产精品一区二区性色av| 欧美韩国理论所午夜片917电影| 91精品国产91久久久久久最新| 国产成人精品久久亚洲高清不卡| 国产精品专区h在线观看| 色噜噜狠狠狠综合曰曰曰88av| 精品色蜜蜜精品视频在线观看| 人人爽久久涩噜噜噜网站| 久久人体大胆视频| 欧美日韩免费一区| 日本成人免费在线| 欧美亚洲国产另类| 日韩av免费一区| 青青精品视频播放| 日韩精品免费在线视频| 成人在线激情视频| 亚洲色图美腿丝袜| 国产美女精品视频免费观看| 欧美成人免费小视频| 欧美视频在线观看 亚洲欧| 中文字幕久热精品视频在线| 91国产中文字幕| 日韩美女福利视频| 国产精品十八以下禁看| 国产欧美一区二区三区在线看| 亚洲人成网7777777国产| 日韩精品视频在线观看网址| 亚洲国产精品久久精品怡红院| 欧美日韩国内自拍| 亚洲性av在线| 久久精品国产久精国产一老狼| 日本国产一区二区三区| 国产精品久久久久久久电影| 91精品国产自产在线| 亚洲视频视频在线| 欧美裸体视频网站| 久久99国产精品自在自在app| 亚洲国产精品高清久久久| 91国自产精品中文字幕亚洲| 日本午夜人人精品| 国产一区二区三区在线播放免费观看| 欧美高清在线视频观看不卡| 国产精品成人在线| 欧美日韩国产在线看| 欧美大片大片在线播放| 亚洲欧美激情视频| 91日韩在线视频| 国产做受高潮69| 91精品视频播放| 久久久久久久激情视频| 日韩在线视频导航| 日韩成人av一区| 在线观看亚洲区| 久久中文字幕在线视频| 国产日韩欧美电影在线观看| 日韩网站免费观看| 欧美xxxx14xxxxx性爽| 国产成人高清激情视频在线观看| 最近免费中文字幕视频2019| 国产精品白丝av嫩草影院| 成人免费直播live| 欧洲永久精品大片ww免费漫画| 日韩av大片在线| 91亚洲国产成人久久精品网站| 久久影院免费观看| 69**夜色精品国产69乱| 国产精品久久国产精品99gif| 亚洲欧美日韩一区二区三区在线| 国产精品免费一区二区三区都可以| 国外视频精品毛片| 国产在线精品自拍| 亚洲激情在线观看视频免费| 欧美性猛交xxxx乱大交| 亚洲成人网av| 国产综合久久久久| 日韩在线视频网| 性色av一区二区三区在线观看| 热re99久久精品国产66热| 欧美激情一级二级| 伊人久久久久久久久久久| 热re91久久精品国99热蜜臀| 亚洲欧美综合图区| 亚洲天堂第二页| 久久久综合av|