編寫php自定義擴展

有兩個理由須要本身編寫PHP擴展。第一個理由是:PHP須要支持一項她還未支持的技術。這一般包括包裹一些現成的C函數庫,以便提供PHP接口。例如,若是一個叫FooBase的數據庫已推出市場,你須要創建一個PHP擴展幫助你從PHP裏調用FooBase的C函數庫。這個工做可能僅由一我的完成,而後被整個PHP社區共享(若是你願意的話)。第二個不是很廣泛的理由是:你須要從性能或功能的緣由考慮來編寫一些商業邏輯。 php

這裏寫圖片描述

1.下載php源碼包:
wget http://tw1.php.net/distributions/php-7.1.9.tar.gzcss

  1. 解壓源碼包 , Zend目錄裏面包含了PHP的Zend Engine源代碼,有些函數和宏的定義咱們須要在這裏面簡單地看一下。
    ext目錄裏面包含了PHP原生的擴展,以及咱們開發本身的擴展時能夠利用的工具,Linux下使用ext_skel,Windows下使用ext_skel_win32.phpweb

  2. 使用./ext_skel --help
    這裏寫圖片描述數據庫

  
  
  
  
  • 1
./ext_skel --extname=module_name

就能夠在ext目錄下生成本身的擴展vim

config.m4配置文件
開發PHP擴展,在寫C代碼以前,要先配置一下這裏。咱們打開能夠看到詳細的註釋說明,dnl是註釋語法。
若是你的擴展用到了外部依賴,就配置–with-hello選項,不然配置–enable-hello選項,刪除這下面3行的del註釋
PHP_ARG_ENABLE(hello, whether to enable hello support,
Make sure that the comment is aligned:
[ –enable-hello Enable hello support])
PHP_ARG_WITH和PHP_ARG_ENABLE這兩個宏用來配置configure選項,一個配置須要外部依賴的,另外一個配置不須要外部依賴的
配置好的內容,在後面執行configure –help時能夠看到。數組

php_hello.h頭文件
相似於C語音的頭文件,包含了一些自定義的結構和函數聲明,在這個demo中暫時不須要改動markdown

hello.c代碼文件
真正的邏輯代碼都在這個文件中,後面會詳細介紹。svg

3、編寫代碼
好了,到這一步咱們終於要開始寫代碼了,打開hello.c文件。
整個擴展的入口是zend_module_entry這個結構,具體的定義能夠在Zend目錄下的zend_modules.h文件中看到,一共有十幾個屬性,快速跳過,咱們暫時只須要」hello world」。函數

  
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
zend_module_entry hello_module_entry = { STANDARD_MODULE_HEADER, "hello", hello_functions, PHP_MINIT(hello), PHP_MSHUTDOWN(hello), PHP_RINIT(hello), /* Replace with NULL if there's nothing to do at request start */ PHP_RSHUTDOWN(hello), /* Replace with NULL if there's nothing to do at request end */ PHP_MINFO(hello), PHP_HELLO_VERSION, STANDARD_MODULE_PROPERTIES };

STANDARD_MODULE_HEADER幫咱們實現了前面6個屬性
「hello」是擴展的名字
hello_functions是擴展包含的所有方法的集合
後面5個宏分別表明5個擴展特定方法
PHP_HELLO_VERSION是擴展的版本號,定義在頭文件中
STANDARD_MODULE_PROPERTIES幫咱們實現了剩下的屬性
暫時都不須要修改,知道這是一個入口就行。順着這個入口,咱們繼續看怎麼給擴展添加方法,在hello_functions[]方法數組中已經有了一個示例方法confirm_hello_compiled,咱們參考它寫咱們的方法hello_world工具

  
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
const zend_function_entry hello_functions[] = { PHP_FE(confirm_hello_compiled, NULL) /* For testing, remove later. */ PHP_FE(hello_world, NULL) PHP_FE_END /* Must be the last line in hello_functions[] */ };

先在擴展的方法數組中添加上hello_world,而後再定義hello_world。找到confirm_hello_compiled方法定義的地方,在它下面依葫蘆畫瓢,php_printf是Zend Engine中的printf方法。

  
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
PHP_FUNCTION(hello_world) { php_printf("Hello World!\n"); RETURN_TRUE; }

最後在編寫完c代碼以後執行

  
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
phpize ./configure --with-php-config=/usr/local/php/bin/php-config make && make install sudo cp /vagrant/php-7.1.9/ext/hello/modules/hello.so /usr/local/php/lib/php/extensions/no-debug-non-zts-20160303/ sudo vim /usr/local/php/etc/php.ini 加上extension=hello.so' #查看最終的效果 php -r 'echo hello_world();'

這裏寫圖片描述

原文:http://www.javashuo.com/article/p-uqdpcqup-p.html

相關文章
相關標籤/搜索