如何編寫一個PHP的C擴展

爲何要用C擴展

C是靜態編譯的,執行效率比PHP代碼高不少。一樣的運算代碼,使用C來開發,性能會比PHP要提高數百倍。IO操做如CURL,由於耗時主要在IOWait上,C擴展沒有明顯優點。php

另外C擴展是在進程啓動時加載的,PHP代碼只能操做Request生命週期的數據,C擴展可操做的範圍更廣。函數

第一步

下載PHP的源代碼,如php-5.4.16。解壓後進入php-5.4.16\ext目錄。輸入 ./ext_skel –extname=myext,myext就是擴展的名稱,執行後生成myext目錄。工具

ext_skel是PHP官方提供的用於生成php擴展骨架代碼的工具。性能

cd myext。能夠看到php_myext.h、myext.c、config.m4等幾個文件。config.m4是AutoConf工具的配置文件,用來修改各類編譯選項。指針

第二步

修改config.m4,將生命週期

dnl PHP_ARG_WITH(myext, for myext support,
dnl Make sure that the comment is aligned:
dnl [  --with-myext             Include myext support])

修改成進程

PHP_ARG_WITH(myext, for myext support,
[  --with-myext             Include myext support])

下邊還有一個 –enable-myext,是表示編譯到php內核中。with是做爲動態連接庫載入的。開發

第三步

修改php_myext.h,看到PHP_FUNCTION(confirm_myext_compiled); 這裏就是擴展函數聲明部分,能夠增長一行 PHP_FUNCTION(myext_helloworld); 表示聲明瞭一個myext_helloworld的擴展函數。rem

而後修改myext.c,這個是擴展函數的實現部分。it

const zend_function_entry myext_functions[] = {
        PHP_FE(confirm_myext_compiled,  NULL)           /* For testing, remove later. */
        PHP_FE(myext_helloworld,  NULL)
        PHP_FE_END      /* Must be the last line in myext_functions[] */
};

這的代碼是將函數指針註冊到Zend引擎,增長一行PHP_FE(myext_helloworld,  NULL)(後面不要帶分號)。

第四步

在myext.c末尾加myext_helloworld的執行代碼。

PHP_FUNCTION(myext_helloworld)
{
        char *arg = NULL;
	int arg_len, len;
	char *strg;
	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
		return;
	}
	php_printf("Hello World!\n");
	RETRUN_TRUE;
}

zend_parse_parameters是用來接受PHP傳入的參數,RETURN_XXX宏是用來返回給PHP數據。

第五步

在myext目錄下依次執行phpize、./configure 、make、make install。而後修改php.ini加入extension=myext.so

執行php -r 「myext_helloworld(‘test’);」,輸出hello world!

相關文章
相關標籤/搜索