欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PHP擴(kuò)展開(kāi)發(fā)入門(mén)教程

 更新時(shí)間:2015年02月26日 10:51:02   投稿:junjie  
這篇文章主要介紹了PHP擴(kuò)展開(kāi)發(fā)入門(mén)教程,本文講解了使用C語(yǔ)言在Linux系統(tǒng)下開(kāi)發(fā)一個(gè)PHP擴(kuò)展應(yīng)該具備的最基本知識(shí),需要的朋友可以參考下

PHP擴(kuò)展開(kāi)發(fā)

我準(zhǔn)備在此系列博文中總結(jié)我有關(guān)PHP擴(kuò)展開(kāi)發(fā)的學(xué)習(xí)和感悟,力圖簡(jiǎn)單清晰地描述在Linux系統(tǒng)下開(kāi)發(fā)一個(gè)PHP擴(kuò)展應(yīng)該具備的最基本知識(shí)。水平較低,難免有錯(cuò)誤,望指出。

準(zhǔn)備工作

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

復(fù)制代碼 代碼如下:

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

注意,我們沒(méi)有指定--prefix選項(xiàng)(同時(shí)也沒(méi)有make install),因?yàn)檫@不是必須的。注意查看輸出信息,也許你需要安裝一些依賴包才能成功編譯PHP。

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

復(fù)制代碼 代碼如下:

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

有一些命令行選項(xiàng)是很有用的:

復(fù)制代碼 代碼如下:

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

擴(kuò)展骨架

PHP的所有官方擴(kuò)展都在源碼的ext目錄下,我們自己寫(xiě)的擴(kuò)展也可以放在該目錄下。注意,該目錄下有個(gè)名為ext_skel的shell腳本,它是用來(lái)生成PHP擴(kuò)展骨架的,使用該腳本,可以幫我們快速創(chuàng)建PHP擴(kuò)展:

復(fù)制代碼 代碼如下:

$ ./ext_skel --extname=myext

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

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

復(fù)制代碼 代碼如下:

$ ./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打印了我們擴(kuò)展的加載情況,如果看不到下面的輸出,則說(shuō)明我們的擴(kuò)展沒(méi)有配置成功,回頭檢查下config.m4文件。

這次編譯應(yīng)該非??欤?yàn)榇蟛糠执a都已經(jīng)編譯過(guò)了。PHP還有另外一種編譯擴(kuò)展的方法(使用動(dòng)態(tài)連接的方式,將擴(kuò)展編譯為.so的文件),不過(guò)我們推薦在開(kāi)發(fā)擴(kuò)展的時(shí)候使用靜態(tài)編譯,因?yàn)檫@樣省去了在配置文件中加載擴(kuò)展的步驟。

一切順利的話,我們的第一個(gè)擴(kuò)展就已經(jīng)可以執(zhí)行了:

復(fù)制代碼 代碼如下:

$ 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.

第一個(gè)命令顯示了我們的擴(kuò)展已經(jīng)被加載。第二個(gè)命令執(zhí)行了ext_skel擴(kuò)展骨架自動(dòng)為我們創(chuàng)建的函數(shù)。當(dāng)然,這個(gè)函數(shù)毫無(wú)意義,不過(guò)我們可以很容易的把這個(gè)函數(shù)改編成hello world。

手動(dòng)創(chuàng)建擴(kuò)展

大部分教程都是以ext_skel擴(kuò)展骨架為原型講述擴(kuò)展開(kāi)發(fā)的,這種做法當(dāng)然很方便快捷。但是我個(gè)人更喜歡純手工開(kāi)發(fā)擴(kuò)展的方式,因?yàn)檫@樣更容易理解其中的每一個(gè)細(xì)節(jié)。

手動(dòng)創(chuàng)建擴(kuò)展,先進(jìn)入ext目錄,創(chuàng)建我們的擴(kuò)展目錄myext2。有幾個(gè)文件是必須的:config.m4,myext2.c和php_myext2.h。

首先,我們來(lái)編寫(xiě)配置文件config.m4:

復(fù)制代碼 代碼如下:

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其實(shí)是autoconf程序使用的配置文件,autoconf是autotools工具箱里重要的組成。完整介紹autoconf的用法是需要很長(zhǎng)時(shí)間的,好在我們這里的用法非常簡(jiǎn)單。

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

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

接下來(lái)編寫(xiě)php_myext2.h頭文件,該文件的命名是PHP擴(kuò)展的規(guī)范 — php_擴(kuò)展名.h:

復(fù)制代碼 代碼如下:

#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底層通過(guò)該宏來(lái)引用我們的擴(kuò)展。可以看出,該宏的命名同樣是有規(guī)范的 — phpext_擴(kuò)展名_ptr。而myext2_module_entry是我們稍后要在.c文件里定義的結(jié)構(gòu)體,它的命名也是規(guī)范的 — 擴(kuò)展名_module_entry。

此外我們還定義了一個(gè)標(biāo)識(shí)我們擴(kuò)展版本號(hào)的宏和一個(gè)函數(shù)原型(通過(guò)PHP_FUNCTION宏,PHP_FUNCTION宏函數(shù)的參數(shù)是外部可使用的函數(shù)名),稍后我們會(huì)來(lái)實(shí)現(xiàn)這個(gè)函數(shù)。

最后來(lái)看下myext2.c文件的實(shí)現(xiàn):

復(fù)制代碼 代碼如下:

#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");
}
/* }}} */

對(duì)比下擴(kuò)展骨架創(chuàng)建的.c文件就會(huì)發(fā)現(xiàn),我們的.c文件非常的簡(jiǎn)單,其實(shí)這些對(duì)一個(gè)最基本的擴(kuò)展來(lái)說(shuō)就已經(jīng)足夠了。

上面的代碼是簡(jiǎn)單而清晰的,大部分注釋已經(jīng)很具說(shuō)明性了。我們?cè)俸?jiǎn)要概括下:

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

注意到我們每一個(gè)文件的命名,變量的命名,空格和縮進(jìn),以及注釋等都是非常規(guī)范的,遵循這些規(guī)范,可以使我們編寫(xiě)的代碼和PHP本身的代碼更加契合,我們也推薦你使用這樣的規(guī)范來(lái)開(kāi)發(fā)PHP擴(kuò)展。

最后,編譯運(yùn)行我們的擴(kuò)展:

復(fù)制代碼 代碼如下:

$ ./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!

相關(guān)文章

  • php模板原理講解

    php模板原理講解

    php各種MVC框架采用頁(yè)面和代碼分離,通過(guò)模板將變量賦值到頁(yè)面,以及模板引擎,那么php模板賦值的原理是什么呢
    2013-11-11
  • PHP各種異常和錯(cuò)誤的攔截方法及發(fā)生致命錯(cuò)誤時(shí)進(jìn)行報(bào)警

    PHP各種異常和錯(cuò)誤的攔截方法及發(fā)生致命錯(cuò)誤時(shí)進(jìn)行報(bào)警

    在日常開(kāi)發(fā)中,大多數(shù)人的做法是在開(kāi)發(fā)環(huán)境時(shí)開(kāi)啟調(diào)試模式,在產(chǎn)品環(huán)境關(guān)閉調(diào)試模式。在開(kāi)發(fā)的時(shí)候可以查看各種錯(cuò)誤、異常,但是在線上就把錯(cuò)誤顯示的關(guān)閉
    2016-01-01
  • Thinkphp 框架擴(kuò)展之Widget擴(kuò)展實(shí)現(xiàn)方法分析

    Thinkphp 框架擴(kuò)展之Widget擴(kuò)展實(shí)現(xiàn)方法分析

    這篇文章主要介紹了Thinkphp 框架擴(kuò)展之Widget擴(kuò)展實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了Thinkphp 框架Widget擴(kuò)展概念、原理、實(shí)現(xiàn)方法及操作注意事項(xiàng),需要的朋友可以參考下
    2020-04-04
  • php操作xml

    php操作xml

    分步學(xué)習(xí)php操作xml:XML概念、DOMDocument對(duì)象、加載xml、讀取/遍歷節(jié)點(diǎn)與屬性、修改屬性/節(jié)點(diǎn)、添加元素/屬性、刪除屬性/節(jié)點(diǎn),學(xué)會(huì)上面這些就可以順利操作XML了。
    2013-10-10
  • Symfony控制層深入詳解

    Symfony控制層深入詳解

    這篇文章主要介紹了Symfony控制層,結(jié)合大量實(shí)例代碼深入分析了Symfony控制器的常見(jiàn)使用技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2016-03-03
  • CI框架裝載器Loader.php源碼分析

    CI框架裝載器Loader.php源碼分析

    前面我們分析了CI框架的session類和安全類文件,今天我們來(lái)分析下CI框架的裝載器Loader.php文件的源碼
    2014-11-11
  • php數(shù)字游戲 計(jì)算24算法

    php數(shù)字游戲 計(jì)算24算法

    輸入任意4個(gè)數(shù)字,然后對(duì)其進(jìn)行+-*/組合,所得數(shù)學(xué)表達(dá)式值等于24
    2012-06-06
  • Zend Framework教程之請(qǐng)求對(duì)象的封裝Zend_Controller_Request實(shí)例詳解

    Zend Framework教程之請(qǐng)求對(duì)象的封裝Zend_Controller_Request實(shí)例詳解

    這篇文章主要介紹了Zend Framework教程之請(qǐng)求對(duì)象的封裝Zend_Controller_Request用法,結(jié)合實(shí)例形式詳細(xì)分析了請(qǐng)求對(duì)象封裝的原理,使用方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2016-03-03
  • PHP編程開(kāi)發(fā)怎么提高編程效率 提高PHP編程技術(shù)

    PHP編程開(kāi)發(fā)怎么提高編程效率 提高PHP編程技術(shù)

    這篇文章主要介紹了PHP編程開(kāi)發(fā)怎么提高編程效率(牢記這20個(gè)點(diǎn))的相關(guān)資料,需要的朋友可以參考下
    2015-11-11
  • 6個(gè)超實(shí)用的PHP代碼片段

    6個(gè)超實(shí)用的PHP代碼片段

    這篇文章主要介紹了10個(gè)超實(shí)用的PHP代碼樣例:黑名單過(guò)濾、隨機(jī)顏色生成器、從網(wǎng)上下載文件、強(qiáng)制下載文件、截取圖片、檢查網(wǎng)站是否宕機(jī),需要的朋友可以參考下
    2015-08-08

最新評(píng)論