2015年6月3日 星期三

PHP extension 開發

系統

  • CentOS 7
  • PHP 5.4.16

下載 PHP原始檔

可至 http://php.net/downloads.php 下載最新版本, 我是使用 5.4.41 版
http://windows.php.net/downloads/releases/php-5.4.41-src.zip  將檔案解壓縮, 上傳到 CentOS 的 /root/php-5.4.41

安裝套件

因為我的 CentOS 選擇最小安裝, 所以在編譯 extension 之前, 需要安裝以下的套件
sudo yum install httpd php php-devel gcc

修改權限

沒修改權限, 會出現 permission denied, 可能是因為我用 windows 下載檔案的關係吧?
chmod 744 /root/php-5.4.41/ext/ext_skel

建立skel檔

vi /root/php-5.4.41/ext/lucars.skel
內容如下
string lucars(string str)

建立extension所需要的檔案

/root/php-5.4.41/ext/ext_skel --extname=lucars --proto=lucars.skel
執行後會在 /root/php-5.4.41/ext 底下建立一個叫做 lucars 的目錄, 裡面包含:
  • config.m4
  • config.w32
  • lucars.c
  • php_lucars.c

編輯 php_lucars.h

vi /root/php-5.4.41/ext/lucars/php_lucars.h
可能是因為 --proto 的關係, 預設會幫忙建立一個 lucars() 的 function.
為了額外宣告另外一個function lucars2(), 所以修改 php_lucars.h, 加上底下這行
PHP_FUNCTION(lucars2);

編輯 lucars.c

vi /root/php-5.4.41/ext/lucars/lucars.c 改寫 PHP_FUNCTION(lucars)
PHP_FUNCTION(lucars)
{
char *str = NULL;
int argc = ZEND_NUM_ARGS();
int str_len;
char *result;
if (zend_parse_parameters(argc TSRMLS_CC, "s", &str, &str_len) == FAILURE)
return;
str_len = spprintf(&result,0,"Hello \"%.78s\"",str);
RETURN_STRINGL(result,str_len,0);
並新增 PHP_FUNCTION(lucars2)
PHP_FUNCTION(lucars2)
{
char *str = NULL;
int argc = ZEND_NUM_ARGS();
int str_len;
char *result;
if (zend_parse_parameters(argc TSRMLS_CC, "s", &str, &str_len) == FAILURE)
                return;
str_len = spprintf(&result, 0,"<a href=\"%.78s\">Link</a>",str);
RETURN_STRINGL(result, str_len,0);
}

修改 config.m4

有人說 PHP_ARG_WITH 跟 PHP_ARG_ENABLE 選一個把註解拿掉就好, 我最後是把 PHP_ARG_ENABLE 的註解(dnl)拿掉, 在 16 ~18 行
PHP_ARG_ENABLE(lucars, whether to enable lucars support,
Make sure that the comment is aligned:
[  --enable-lucars           Enable lucars support])

 進行編譯

使用 phpize 進行編譯, 參考  php-config 的設定(位置請依照主機的設定)
/usr/bin/phpize ./configure --with-php-config=/usr/bin/php-config 進行編譯, 測試, 安裝
make
make test
make install clean

啟用 extension

編譯好的 lucars.so 檔放在 /usr/lib64/php/modules, 修改 php.ini
vi /etc/php.ini 加入 lucars.so
extension=/usr/lib64/php/modules/lucars.so 結束編輯之後, 重啟 Apache
systemctl restart httpd  就可以直接使用 lucars() 跟 lucars2() 這兩個 function 了