程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> php的擴展和嵌入--c擴展開發helloworld

php的擴展和嵌入--c擴展開發helloworld

編輯:關於PHP編程

在linux下面完成了LAMP的配置環境之後,就可以進行php的擴展開發了。

php中的擴展開發都在源碼包的/ext文件夾之下,可以看到這裡已經有了很多開發好的擴展。比如與數據庫相關的mysql以及xml處理的模塊等等。

首先建立一個文件夾:

mkdir hello

在進入這個文件夾之後,先創建並打開一個配置文件:

vim config.m4

這個給出一個配置問題的實例:

1 PHP_ARG_ENABLE(sample, whether to enable SAMPLE support,
2 [ --enable-sample Enable SAMPLE support])
3 if test "$PHP_SAMPLE" = "yes"; then
4    AC_DEFINE(SAMPLE, 1, [Whether you have SAMPLE])
5   PHP_NEW_EXTENSION(sample, sample.c, $ext_shared)
6 fi
* 這個配置文件創造了一個--enable-hello的配置選項,而PHP_ARG_ENABLE的第二個選項會在配置的時候顯示出來
* PHP_ARG_ENABLE的第三個參數則是在調用./configurehelp的時候會顯示出來
* 為什麼有時候用enable-xxx,有時候用with-xxx?enable是可以關掉的,但是with需要額外的第三方的庫
* 如果說--enable-hello在配置的時候有了,那麼$PHP_HELLO這個參數就會被設為yes,那麼才有接下來的操作
* PHP_NEW_EXTENSION則是要聲明所有需要的源文件:PHP_NEW_EXTENSION(sample, sample.c sample2.c sample3.c, $ext_shared)
* 最後一個參數在building一個shared module的時候一般是這麼些的。$ext_shared

下面列出在config文件中可能有的配置選項: * PHP_ARG_WITH 或者 PHP_ARG_ENABLE 指定了PHP擴展模塊的工作方式,前者意味著不需要第三方庫,後者正好相反;
* PHP_REQUIRE_CXX 用於指定這個擴展用到了C++;
* PHP_ADD_INCLUDE 指定PHP擴展模塊用到的頭文件目錄;
* PHP_CHECK_LIBRARY 指定PHP擴展模塊PHP_ADD_LIBRARY_WITH_PATH定義以及庫連接錯誤信息等;
* PHP_ADD_LIBRARY(stdc++,”",EXTERN_NAME_LIBADD)用於將標准C++庫鏈接進入擴展
* PHP_SUBST(EXTERN_NAME_SHARED_LIBADD) 用於說明這個擴展編譯成動態鏈接庫的形式;
* PHP_NEW_EXTENSION 用於指定有哪些源文件應該被編譯,文件和文件之間用空格隔開;
接下來看頭文件:php_sample.h
1  ?#ifndef PHP_SAMPLE_H
2  /* 防止兩次引入 */
3  #define PHP_SAMPLE_H
4  /* 定義擴展的性質 */
5  #define PHP_SAMPLE_EXTNAME "sample"
6  #define PHP_SAMPLE_EXTVER "1.0"
7  /* 當在php的源碼樹之外build的時候,引入配置選項, 在使用phpize工具時,一般都是先定義的 */
8  #ifdef HAVE_CONFIG_H
9  #include "config.h"
10  #endif
11  /* 引入php標准頭文件 */
12  #include "php.h"
13  PHP_FUNCTION(hello_world);//聲明擴展中的函數
14   /* 定義入口點的符號,zend在加載這個module的時候會用*/
15  extern zend_module_entry sample_module_entry;
16  #define phpext_sample_ptr &sample_module_entry
17  #endif /* PHP_SAMPLE_H */
最後再注意兩點: * php.h則是一定要引入的
* 聲明zend_module_entry被聲明為extern,所以當擴展被以extension=。。的形式加載的時候,Zend能夠通過dlopen()和dlsym()找到它。


最後來看源文件sample.c:
#include "php_sample.h"

    static function_entry php_sample_functions[] = {
    PHP_FE(sample_hello_world, NULL)//任何擴展中的函數都要在這裡聲明。把函數名輸出到了用戶空間中
    { NULL, NULL, NULL }
    };
zend_module_entry sample_module_entry = { //創建一個入口
    #if ZEND_MODULE_API_NO >= 20010901 //這個是一個版本號
    STANDARD_MODULE_HEADER,
    #endif
    PHP_SAMPLE_EXTNAME,
    php_sample_functions, /* Functions 這裡是把php_function加入到Zend中去*/
    NULL, /* MINIT */
    NULL, /* MSHUTDOWN */
    NULL, /* RINIT */
    NULL, /* RSHUTDOWN */
    NULL, /* MINFO */
    #if ZEND_MODULE_API_NO >= 20010901
    PHP_SAMPLE_EXTVER,
    #endif
    STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_SAMPLE
ZEND_GET_MODULE(sample)
#endif //這塊區域是當擴展被動態加載的時候,為Zend添加一個引用,記得要添加上就行。
/*真正的函數體的部分*/
PHP_FUNCTION(sample_hello_world)
{
    php_printf("Hello World!\n");
}
這就是源碼的內容了。
接下來需要進行擴展的生成: phpize ./configure --enable-sample make sudo make install 在執行完這些語句之後,需要在php.ini中添加這個擴展名:extension=sample.so 然後再重啟一下apache sudo /etc/init.d/httpd restart
接下來在phpinfo頁面中查看是否sample這個擴展已經有了,如果有了,那麼在下面test.php中驗證:
如果打印除了"Hello World!",那麼就說明這個php擴展開發成功了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved