簡單點,先來實現一個PHP擴展的hello world。
注意,如下全部操做都是基於linux系統(推薦centos和ubuntu, Mac系統應該相似 ),PHP5.5以上,建議讀者使用5.5以上版本測試本文例程,PHP內核是由C語言寫成的,因此擴展基本也是用C/C++編寫。
話很少說,請睇下面:
1、下載PHP源碼到本地目錄php
解壓後進入PHP源碼的ext目錄,在此目錄下有一個名爲ext_skel
的shell腳本文件。接下來咱們將使用它來生成咱們的擴展的基本骨架。固然,若是你夠牛也能夠不用它,直接本身編寫必要的文件。linux
2、生成擴展的基本骨架nginx
在ext目錄執行命令:git
./ext_skel --extname=foobar
若是在此目錄沒有寫權限請自覺加sudo。命令執行完畢後輸出:github
Creating directory foobar Creating basic files: config.m4 config.w32 .svnignore foobar.c php_foobar.h CREDITS EXPERIMENTAL tests/001.phpt foobar.php [done]. To use your new extension, you will have to execute the following steps: 1. $ cd .. 2. $ vi ext/foobar/config.m4 3. $ ./buildconf 4. $ ./configure --[with|enable]-foobar 5. $ make 6. $ ./sapi/cli/php -f ext/foobar/foobar.php 7. $ vi ext/foobar/foobar.c 8. $ make Repeat steps 3-6 until you are satisfied with ext/foobar/config.m4 and step 6 confirms that your module is compiled into PHP. Then, start writing code and repeat the last two steps as often as necessary.
人品好的話將看到上面的輸出,這表示已成功生成名爲foobar
的PHP擴展的基本骨架,在當前目錄生成了一個foobar
的文件夾,咱們擴展的全部代碼都將放在此目錄下(使用了第三方的庫的擴展另當別論)。先彆着急弄懂上面提示的內容,之後你會知道的,就像小時候媽媽常常跟你說:等你長大了就懂了!shell
3、編輯config.m4文件apache
ls
擴展目錄foobar,發現裏面有幾個文件:ubuntu
config.m4 config.w32 CREDITS EXPERIMENTAL foobar.c foobar.php php_foobar.h tests
用VIM打開擴展目錄下的config.m4文件,找到下面幾行:vim
16 dnl PHP_ARG_ENABLE(foobar, whether to enable foobar support, 17 dnl Make sure that the comment is aligned: 18 dnl [ --enable-foobar Enable foobar support])
前面的數字是它所在的行數(下同),不是文件內容,去掉16和18行前面dnl
字符,dnl
註釋開始,咱們要把這兩行的註釋符號去掉,17行不用管。wq
保存文件。
config.m4文件其實有不少內容,初始入門教程就不仔細說明各部份內容,由於實在我也不太懂!它的做用是配置擴展的行爲,好比說明擴展編譯選項,是否使用第三方庫,擴展的源碼組成等等。centos
4、編輯php_foobar.h文件:聲明一個函數
php_foobar.h
是一個C頭文件,咱們須要在這個頭文件裏聲明一個方法
vim編輯php_foobar.h
文件,找到下面這一行:
47 PHP_FUNCTION(confirm_foobar_compiled); /* For testing, remove later. */
這上ext_skel
工具生成擴展骨架的時候自動聲明的一個函數,僅用於測試,你能夠去掉,也能夠保留!在這一行的下面添加一行:
48 PHP_FUNCTION(halo);
這就聲明瞭一個名爲halo
的PHP空間的函數,在PHP的代碼裏就能夠像普通函數同樣調用它。固然,目前到這一步還不行,由於這裏只是聲明,尚未定義它的行爲。咱們將在foobar.c
文件中編寫它的函數體。
4、編輯foobar.c文件:定義函數體
foobar.c
是擴展主要實現的地方,找到下面幾行:
41 const zend_function_entry foobar_functions[] = { 42 PHP_FE(confirm_foobar_compiled, NULL) /* For testing, remove later. */ 43 PHP_FE_END /* Must be the last line in foobar_functions[] */ 44 };
在42行下面添加PHP_FE(halo, NULL)
。注意不要添加任何分號。以下:
41 const zend_function_entry foobar_functions[] = { 42 PHP_FE(confirm_foobar_compiled, NULL) /* For testing, remove later. */ 43 PHP_FE(halo, NULL) 44 PHP_FE_END /* Must be the last line in foobar_functions[] */ 45 };
這一步是向PHP空間註冊一個函數,名字就是剛纔在php_foobar.h
文件聲明的halo
。
接下來是真正編寫halo
函數實現的時候。
在文件末尾添加如下代碼:
169 PHP_FUNCTION(halo){ 170 php_printf("hello world!"); 171 }
從代碼看出:halo
函數只是打印一串字符串hello world
,不作其餘任何事情。
foobar.c
文件內容不少,每一個代碼段都有相應的註釋說明,仔細研究一下,應該仍是大概能懂是什麼意思!若是看不明白也不要緊,仍是媽媽那句話:等你長大(看多)了就懂了
OK!編碼完畢,下面就是把擴展編譯進PHP,供PHP代碼調用!
5、編譯安裝擴展
擴展編譯分動態編譯和靜態編譯兩種方法!今天咱們先討論動態編譯。有興趣的同窗能夠自行研究一下靜態編譯是什麼鬼!
在擴展目錄中執行phpize
命令。必定要在擴展的目錄執行纔有效,不然將獲得一個錯誤提示。
若是提示沒有找到命令,請檢查系統沒有安裝php-dev
工具集,若是是源碼編譯安裝的PHP,通常在php的bin目錄下面,若是經過yum
或apt
安裝的PHP
請確認是否安裝過php-dev
或者php-devel
,安裝過的話應該直接就能運行phpize
命令。也可經過find / -name phpize
命令來找到phpize
的路徑,而後帶路徑執行,若是系統安裝了多個版本的PHP,最好是指定路徑的phpize
來指定使用的PHP版本!還找不到的話就GOOGLE一下吧!
phpize
命令的正常輸出以下:
Configuring for: PHP Api Version: 20121113 Zend Module Api No: 20121212 Zend Extension Api No: 220121212
它代表的是當前使用的PHP內核的版本。
執行完phpize
命令,細心的你會發現擴展目錄下多出了好多文件,個人意見是不用管這些文件是幹嗎用的,固然有興趣也能夠研究一下!
下一步就是configure
,詳細命令以下:
./configure --enable-foobar --with-config-path=/usr/local/php/bin/php-config
configure
須要兩個選項:--enable-foobar
表示啓用這個擴展; --with-config-path=/usr/local/php/bin/php-config
, 指定了php-config
的路徑,通常源碼編譯安裝的PHP和多版本環境都須要指定這個選項,apt
和yum
安裝的都是在默認路徑,能夠不特別指定。
configure
以後又多了好多文件,再一次無視它們吧!命令輸出好長的一陀東西。
configure
完以後就是make
了。
什麼?command not found
?先安裝gcc
和make
吧! 方法請Google!
順利make
完以後,會在擴展的目錄下的modules
子目錄多了一個foobar.so
的文件,
它就是咱們剛纔編寫的擴展的最終產物。聰明的你必定已經想到:這TM不就是個動態庫嗎?而我只能說:你說對了!動態編譯產生的是動態庫文件。
OK,擴展編譯完了,須要在PHP中使用擴展,複製foobar.so
的完整路徑,vim打開PHP的配置文件php.ini
,在文件的末尾加入如下內容:
extension=/root/php-5.5.38/ext/foobar/modules/foobar.so #這是在個人系統foobar.so路徑
保存退出,重啓一下php-fpm(或apache,nginx什麼的,若是不肯定,就都重啓吧!請不要在生產環境瞎搞)
有些人就忍不住要問一下了:爲何有些擴展在php.ini
的配置中不用帶路徑?其實咱們的擴展同樣也是能夠的。在make
命令以後多執行一步:make install
,若是不是root
權限,請自覺加sudo
或切到root
用戶下執行。擴展就會安裝到相應PHP版本的默認擴展加載路徑!而後在php.ini
的配置中就只要簡單寫上擴展名加so
便可.
extension=foobar.so
至此,一個簡單的PHP擴展就完成了。是否是有點小激動?
下面驗證一番,在WEB目錄新建一個php文件,如info.php
,寫入以下代碼:
<?php phpinfo();
地球人都知道這個函數調用是作什麼的吧?
在瀏覽器執行這個文件!看到如下輸出就說明擴展安裝成功了:
直接修改info.php
文件吧,調用咱們剛纔在擴展中定義的函數:
<?php halo();
刷新瀏覽器,若是人品不太壞的話應該就能看到如下的輸出:
hello world!
BingGo!
若是你以爲這文章不錯,請給我點個贊吧^_^!
6、擴展閱讀