linux開發php c擴展實例

php取得成功的一個主要原因之一是它擁有大量的可用擴展,web開發者無論有何種需求,這種需求最有可能在php發行包裏找到
php發行包包括支持各種數據庫,圖形文件格式,壓縮,XML技術擴展在內的許多擴展,PHP擴展(PECL)跟php引擎一樣都是使用c語言開發

php擴展開發需要注意什麼?
1、開發擴展比使用PHP開發相同功能成本與難度都要更高
2、後期維護不易
3、系統及PHP版本更新導致的一些兼容性問題
4、測試服務器和正式服務器的系統版本、php版本、gcc版本、glibc版本都要保持一致


什麼時候需要開發php擴展?
1、對效率要求很高,特別是運算效率
2、功能與業務無關或關聯很小,相對抽象
3、功能基本不會變動,且不會很複雜
4、功能使用php無法實現的或者資源無法訪問

系統環境:
CentOS release 6.6 (Final) 64位
gcc version 4.4.7, Glibc 2.12
PHP 5.3.3 (cli)

php c擴展開發步驟:這裏簡單以實現兩數相乘並返回結果爲例

第一步,生成代碼
php爲了擴展開發的方便,提供了一個類似代碼生成器的工具ext_skel,--extname=test中的test是自定義的函數名稱
下載和系統php版本一致的源碼包,我默認yum安裝,php版本是5.3.3,所以下載php-5.3.3.tar.gz

cd /usr/local/
tar -zxvf php-5.3.3.tar.gz 
cd php-5.3.3/ext/
./ext_skel --extname=test
可以看到目錄下新增了一個test文件夾,這時候,test這個擴展的代碼框架就已經出來了


第二步,修改配置
進入test文件夾下 
cd test
然後修改config.m4文件將10、11、12三行最前面的dnl刪除掉,就是將
dnl PHP_ARG_WITH(test, for test support,
dnl Make sure that the comment is aligned:
dnl [  --with-test             Include test support])
修改爲
PHP_ARG_WITH(test, for test support,
Make sure that the comment is aligned:
[  --with-test             Include test support])


第三步,實現功能

頭文件php_test.h中聲明一個函數test,方法:
將45行左右的
PHP_FUNCTION(confirm_test_compiled);
修改爲:
PHP_FUNCTION(test);
源代碼test.c中實現這個函數,方法:
將154行左右的
PHP_FUNCTION(confirm_test_compiled)
{
	char *arg = NULL;
	int arg_len, len;
	char *strg;


	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
		return;
	}


	len = spprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "test", arg);
	RETURN_STRINGL(strg, len, 0);
}
替換爲:
PHP_FUNCTION(test){
    /*定義一個int 型變量*/
    long a;
    long b;
    char *c;
    /* 字符串在c中使用指針,並且需要指定長度*/
    int c_len;
    /* 此處字符串一個s 對應兩個參數*/
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lls", &a, &b,&c,&c_len) == FAILURE) {
		return;
	}
    char * str;
    int len = spprintf(&str, 0, "%s:%d\n",c,a*b);
    /*可以在zend_api下查看*/
    RETURN_STRINGL(str, len, 0);
}

注意,還需要將test函數註冊到zend_api中,否則會報not found
const zend_function_entry test_functions[] = {
	/*擴展定義的函數*/
    PHP_FE(test,NULL)
    {NULL, NULL, NULL}    /* Must be the last line in test_functions[] */
};

說明:
1、PHP_FUNCTION:是PHP核心定義的一個宏,與ZEND_FUNCTION相同,用於定義擴展函數,實際生成的函數名稱爲zif_ip2long32。
2、zend_parse_parameters:由於PHP爲弱類型語言,而C是強類型,因此需要使用該函數用於接收PHP傳入的參數,並進行一定的類型轉換,將PHP的變量轉爲C語言能夠辨認的類型。
 
第四步,編譯擴展
/usr/bin/phpize  #生成configure文件
./configure --with-php-config=/usr/bin/php-config #替換爲自己環境的php-config路徑
make && make install
成功會提示:Installing shared extensions:     /usr/lib64/php/modules/

第五步,添加擴展
echo "[test]" >> /etc/php.ini  
echo "extension = test.so" >> /etc/php.ini  
命令行查看擴展
php -m|grep test



重啓httpd服務
service httpd restart

第六布,測試
test.php
<?php
echo test(10,20,"result");
?>
結果:



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章