本文主要跟大家介紹從零開始寫 PHP 擴展,我們會從如何產生y一個php擴充講起,希望能幫助大家。
PHP 是用 C 語言寫的。對每個 PHPer 來說,都有內心的一種希望寫擴充的衝動了吧。然而,缺乏一個很好的切入點。 Google 上搜尋 PHP 擴充功能開發,大部分都是複製品文章,甚至有些人連操作都沒有操作過就搬運在了自己的部落格。不過也有幾篇好教程,但是都是 PHP 5 時代的產物,隱藏著非常多的坑。我會將我自己慢慢踩坑的過程記錄下來,也許這就成了其它人的「教學」了吧。
產生一個擴充功能
想必很多人已經看到很多網路上的教學了。大多都是教我們執行這個指令: $./ext_skel--extname=extname。但是,當你 clone 了 PHP 原始碼後會發現,master 分支下並沒有 ext/ext_skel這個檔案。所以,我總結了一下:
如果你是直接下載PHP 的源碼,或者在已經release 的版本分之下,你可以執行這個命令
$ cd ext $ ./ext_skel --extname=extname
如果你是直接在master分支下,只有 ext_skel.php文件,這個時候你就直接可以執行這個PHP 文件
$ cd ext $ php ext_skel.php --ext extname
由於我是直接在master 分支下開發的,所以後面的都是默認在master 分之下的操作。
產生了擴充功能之後,我們會看到四個檔案和一個資料夾。現在這個階段,我們只需要用到兩個文件, .c文件和 .h文件。
一個小坑
在我們產生好擴充之後,我們可以試著編譯
$ phpize $ ./configure $ make &&make test
我們會驚訝地發現,編譯的時候會有一個 warning。
warning:implicitdeclaration of function 'ZEND_PARSE_PARAMETERS_NONE'isinvalid inC99 [-Wimplicit-function-declaration] ZEND_PARSE_PARAMETERS_NONE(); ^
1warning generated.
然後你再執行 make test發現有一個測試沒有通過。沒錯,腳本為我們產生好的文件,居然通不過自己的測試。有沒有覺得很詭異。我們來看看 warning 的具體資訊。找不到函數 ZEND_PARSE_PARAMETERS_NONE。看了一下文件,發現在第 15 行。看看這個函數名大概也能猜出來是什麼意思了。於是我去 PHP 原始碼裡搜了一下。可是我們發現了這樣一個宏定義。
#ifndefzend_parse_parameters_none #definezend_parse_parameters_none() zend_parse_parameters(ZEND_NUM_ARGS(),"") #endif
替換掉原來的大寫之後,就沒有 warning 了。這也算是官方給我們挖了一個小坑吧。雖然大寫的有巨集定義,但是為什麼會報錯,我也不太清楚了。
定義一個函數
我想,大多數人寫擴展,肯定至少希望實作一個函數,不會是要幾個全域變數就去寫個擴展的吧(霧
這裡PHP 給我們了一個有用的巨集PHP_FUNCTION。最後會被翻譯成 voidzif_name(zend_execute_data*execute_data,zval*return_value)
同時我們看到有定義了這麼一個陣列
constzend_function_entry cesium_functions[]={ PHP_FE(cesium_test1,arginfo_cesium_test1) PHP_FE(cesium_test2,arginfo_cesium_test2) PHP_FE_END }; constzend_function_entry cesium_functions[]={ PHP_FE(cesium_test1,arginfo_cesium_test1) PHP_FE(cesium_test2,arginfo_cesium_test2) PHP_FE(name,NULL) PHP_FE_END };
記住,結尾不要加分號或逗號。 ,我們可以個這個函數一個輸出
PHP_FUNCTION(name) { php_printf("Hellon"); }
編譯安裝完了之後我們就可以使用這個函數了。的編譯
以上是PHP擴充基礎學習的詳細內容。更多資訊請關注PHP中文網其他相關文章!