一次失敗的PHP擴充套件開發之旅
阿新 • • 發佈:2019-02-15
2. 進入php原始碼包的ext目錄,藉助ext_skel工具生成外掛架子程式碼
cd ext
./ext_skel --extname=demo
3. 編輯config.m4,開啟PHP_ARG_WITH或者PHP_ARG_ENABLE選項(說實話區別仍沒搞清楚,求達人指點),新增C++支援、依賴路徑等
PHP_ARG_ENABLE(demo, whether to enable demo support, [ --enable-demo Enable demo support]) if test "$PHP_DEMO" != "no"; then PHP_REQUIRE_CXX() PHP_ADD_LIBRARY(stdc++, 1, EXTRA_LDFLAGS) PHP_ADD_INCLUDE(/root/spp/module/include/) PHP_ADD_INCLUDE(/root/spp/module/include/spp_incl/) PHP_NEW_EXTENSION(demo, demo.cpp, $ext_shared) fi
4. 編輯demo.cpp,新增擴充套件定義和實現(函式、類、變數 ...),這裡僅僅給出函式定義示例,類相關的有興趣的讀者自行根據附錄摸索。這裡給出的sendrecv函式定義比較有代表性,其中第3個引數rsp為引用引數,負責將接收到的資料返回給PHP呼叫方
ZEND_BEGIN_ARG_INFO_EX(arginfo_sendrecv, 0, 0, 7) ZEND_ARG_INFO(0, req) ZEND_ARG_INFO(0, req_len) ZEND_ARG_INFO(1, rsp) ZEND_ARG_INFO(0, rsp_len) ZEND_ARG_INFO(0, ip) ZEND_ARG_INFO(0, port) ZEND_ARG_INFO(0, timeout) ZEND_END_ARG_INFO() PHP_FUNCTION(sendrecv) { char *req = NULL; int req_str_len = 0; long req_len = 0; zval *rsp = NULL; long rsp_len = 0; char *ip = NULL; int ip_str_len = 0; long port = 0; long timeout = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "slzlsll", &req, &req_str_len, &req_len, &rsp, &rsp_len, &ip, &ip_str_len, &port, &timeout) == FAILURE) { return; } struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(std::string(ip, ip_str_len).c_str()); addr.sin_port = htons(port); char *rsp_buf = (char *)emalloc(rsp_len); int rsp_buf_len = rsp_len; if (int ret = mt_udpsendrcv(&addr, req, req_len > req_str_len ? req_str_len : req_len, rsp_buf, rsp_buf_len, timeout)) { efree(rsp_buf); RETURN_LONG(ret); } zval_dtor(rsp); ZVAL_STRINGL(rsp, rsp_buf, rsp_buf_len, 0); RETURN_LONG(0); }
const zend_function_entry demo_functions[] = {
PHP_FE(sendrecv, arginfo_sendrecv)
PHP_FE_END /* Must be the last line in demo_functions[] */
};
5. 一切準備就緒,可以編譯擴充套件了,我個人比較喜歡動態編譯(靜態編譯需要重新編譯php原始碼,太耗時費力),生成的.so位於當前擴充套件的modules目錄下
/usr/local/bin/phpize ./configure --with-php-config=/usr/local/bin/php-config make
6. 編輯php.ini檔案,新增新的擴充套件,然後就可以愉快地在PHP程式碼中呼叫新擴充套件了
extension_dir="/somewhere/modules"
extension="demo.so"
extension="xxxx.so"