>
鑰匙要點
注意:安裝上的PHP-CPP文檔指出,暫時,它“僅支持單線讀取PHP安裝”,因為“內部Zend Engine使用了非常奇怪的系統來確保線程安全性”。未來的發行版可能支持多線Readed PHP安裝,但讓我們暫時記住這一點,並遵守其當前限制。幸運的是,大多數PHP安裝都應該是“單線讀取的PHP安裝”。
>> php-cpp寫在C 11中。因此,我的Ubuntu 12.04 LTS中安裝的G較舊版本不支持它。我們需要將G編譯器升級到上述4.8.x版本。有一篇文章詳細介紹了進行升級的步驟。請按照列出的說明進行操作。
>另外,PHP-CPP彙編將使用php.h標頭文件。除非安裝PHP-DEV,否則通常在Ubuntu框中缺少此文件。我們可以通過發出此命令來安裝與PHP5相關的開發文件:
<span>sudo apt-get install php5-dev</span>
>升級G並安裝必要的標頭文件後,我們可以發布以下命令以編譯和安裝PHP-CPP庫文件(libphpcpp.so):
<span>make && sudo make install</span>
>。 PHP-CPP LIB的安裝現已完成。這非常簡單,我們現在可以繼續進行編程部分。
在這樣做之前,我們將討論PHP-CPP中使用的一些重要概念和術語。完整的文檔可以在其官方網站上找到,並鼓勵每個人在執行任何真正的編程之前閱讀它。骨架(空)擴展項目文件
PHP-CPP提供了一個骨架擴展項目,其中包含以下3個文件:
makefile:示例製作文件以編譯擴展名
>更改ini_dir = /etc/php5/conf.d匹配系統的配置。就我而言,它是ini_dir = /etc/php5/cli/conf.d。我修改了INI路徑,以首先啟用PHP CLI環境的擴展。
>
<span>sudo apt-get install php5-dev</span>
在PHP-CPP提供的空項目中,此文件僅包含一個函數:get_module(),該函數下面摘錄:
<span>make && sudo make install</span>
>目前,讓我們更改此行以匹配我們打算創建的擴展名:
接下來,我們需要將所需的文件複製到適當的文件夾中:
<span><span>#include <phpcpp.h></span> </span> <span>/** </span><span> * tell the compiler that the get_module is a pure C function </span><span> */ </span><span>extern "C" { </span> <span>/** </span><span> * Function that is called by PHP right after the PHP process </span><span> * has started, and that returns an address of an internal PHP </span><span> * strucure with all the details and features of your extension </span><span> * </span><span> * @return void* a pointer to an address that is understood by PHP </span><span> */ </span> PHPCPP_EXPORT <span>void *get_module() </span> <span>{ </span> <span>// static(!) Php::Extension object that should stay in memory </span> <span>// for the entire duration of the process (that's why it's static) </span> <span>static Php::Extension extension("yourextension", "1.0"); </span> <span>// @todo add your own functions, classes, namespaces to the extension </span> <span>// return the extension </span> <span>return extension; </span> <span>} </span><span>} </span>
然後,我們可以通過PHP -I |將擴展名驗證在CLI中加載。 GREP骨架,終端應顯示類似的東西:
><span>static Php::Extension extension("skeleton", "1.0"); // To be humble, we can change the version number to 0.0.1</span>
(回想一下skeleton.ini是我們修改的文件,其中包含擴展名= skeleton.so line。)
> 到目前為止,我們已經使用PHP-CPP進行了編譯並安裝了我們的第一個PHP擴展。當然,此擴展程序還沒有任何作用。現在,我們將創建第一個功能,以進一步了解建立PHP擴展的過程。
“你好,泰勒”功能
>
>根據“註冊本機函數”上的PHP-CPP文檔,它支持四種類型的功能簽名:
在這種情況下,我使用第二個簽名,並且參數以數組形式(PHP功能)按值傳遞。現在,讓我們編譯並安裝擴展程序。如果一切順利進行,新的骨架將復製到擴展名目錄。
<span>make && sudo make install</span>
我們可以編寫一個簡單的腳本來測試剛剛創建的函數:
<span>cp -f skeleton.so /usr/lib/php5/20121212 </span><span>cp -f skeleton.ini /etc/php5/cli/conf.d</span>
>我們將回到以後觀察到的內容。
在main.cpp中,我們添加了另一個函數swap():
>
<span>sudo apt-get install php5-dev</span>
我們明確地說:
<span>make && sudo make install</span>
將有兩個參數(a和b);
>
>第一個呼叫(交換($ a,$ b))顯示了預期的結果:20 | 10。該函數交換了兩個數字。<span>extension=skeleton.so</span>
第二個通話是出乎意料的:我們告訴PHP我們要交換兩個數字!但是它只是忽略了第二個參數傳遞的是字符串,並且無論如何都進行交換!
好吧,從某種意義上說,仍然可以預期。 PHP並沒有真正區分數字類型和字符串類型。這種行為符合PHP標準。同樣,由於這種行為,我們沒有,也不能使用C內部類型作為功能(TEMP)中使用的臨時變量,而是使用PHP ::值作為變量類型。第三個通話將起作用。第一個var_dump將顯示DateTime對象,第二個將顯示整數。這是某種程度上出乎意料的(至少對我來說)。畢竟,對象與數字/字符串完全不同。但是,在考慮到這種“互換”行為在PHP中也可行之後,它與PHP的奇怪之處相符。
>那麼,這是否意味著“類型”規範不會產生任何影響?並不真地。為了進一步闡述這一點,我們創建了第三個功能:
我們這樣註冊了此功能:
測試代碼將是這樣的:
><span><span>#include <phpcpp.h></span> </span> <span>/** </span><span> * tell the compiler that the get_module is a pure C function </span><span> */ </span><span>extern "C" { </span> <span>/** </span><span> * Function that is called by PHP right after the PHP process </span><span> * has started, and that returns an address of an internal PHP </span><span> * strucure with all the details and features of your extension </span><span> * </span><span> * @return void* a pointer to an address that is understood by PHP </span><span> */ </span> PHPCPP_EXPORT <span>void *get_module() </span> <span>{ </span> <span>// static(!) Php::Extension object that should stay in memory </span> <span>// for the entire duration of the process (that's why it's static) </span> <span>static Php::Extension extension("yourextension", "1.0"); </span> <span>// @todo add your own functions, classes, namespaces to the extension </span> <span>// return the extension </span> <span>return extension; </span> <span>} </span><span>} </span>
>當我們通過正確的類類型(SampleClass)傳遞時,對SwapoBject()的第一個調用將起作用。第二個將失敗,顯示“可捕獲的致命錯誤:參數1傳遞給swapobject()必須是SampleClass的實例,是給定的另一個類別的實例...”。
<span>static Php::Extension extension("skeleton", "1.0"); // To be humble, we can change the version number to 0.0.1</span>
>我們介紹了擴展項目文件,功能簽名,功能導出/註冊和功能參數類型。
>在下一篇文章中,我們將進一步詳細介紹PHP-CPP中的一些關鍵功能,並提供現實世界中的用例,展示了使用php-cpp的C類和名稱空間實現的使用。
>
>關於PHP擴展開發的常見問題(常見問題解答)我可以使用php-cpp創建PHP 7的擴展名。
是的,PHP-CPP與PHP 7兼容。但是,您需要確保使用最新版本的PHP-CPP,因為較早的版本可能不支持PHP 7。php-cpp提供一個名為php ::異常的類,您可以用來從C代碼中拋出異常。這些例外可以像其他任何PHP例外一樣在您的PHP代碼中捕獲和處理。
>如何從我的C代碼中調用PHP函數?
以上是通過PHP-CPP開始PHP擴展開發的詳細內容。更多資訊請關注PHP中文網其他相關文章!