使用C和PHP-CPP開發PHP擴展:高級
使用C 和PHP-CPP開發PHP擴展:高級主題和最佳實踐
關鍵要點
- 使用C 和PHP-CPP開發PHP擴展涉及高級主題,例如返回“this”指針、返回複雜對象指針、公開
__toString
魔術方法、鏈接成員函數調用以及PHP中的異常拋出和處理。 - 對於需要在未來用於非PHP項目的軟件、數據結構或算法的項目,或者需要使用尚未作為PHP擴展提供的工具或庫的項目,PHP-CPP庫是理想的選擇。它還提供C/C 代碼的性能優勢,同時保持結構化、面向對象的代碼,便於理解和維護。
- PHP-CPP庫可用於個人和商業項目。但是,雖然庫本身是免費的,但可能需要時間和資源來學習如何有效地使用它並維護PHP擴展。
- 使用C 進行PHP擴展開發的常見挑戰包括正確管理內存、處理錯誤和異常以及PHP和C 之間的接口。可以通過深入了解PHP和C 、使用良好的編程實踐以及利用PHP-CPP提供的功能和工具來克服這些挑戰。
在我之前的文章中,我介紹了使用C (第一篇文章和第二篇文章)創建PHP擴展的PHP-CPP庫。在後一篇文章中,我演示了使用Complex類進行複數運算的編寫PHP擴展的面向對象方面。
該介紹並不完整,因為該文章的主要重點更多地放在演示PHP-CPP的面向對象能力上,而不是面向對象的實現細節上。
在本文中,我們將進一步深入研究Complex庫的開發,添加更多成員函數,並解決使用PHP-CPP編寫具有面向對像功能的PHP擴展中的一些高級主題:
- 返回this指針;
- 返回Complex對象指針,即Complex *;
- 公開
__toString
魔術方法; - 鍊式成員函數調用;
- 拋出異常並在PHP中處理它
完整的Complex庫源代碼以及測試PHP腳本位於此Github存儲庫中。
讓我們開始吧。
準備工作
在第一篇文章中解釋了準備環境的整個過程。
在C 中返回this指針
如第二篇文章所述,我們使用成員函數對複數執行各種數學運算。在此演示中,我們將實現四個這樣的函數:add、sub、mul和div。我將首先解釋前三個。 div函數涉及異常處理,稍後將討論。
讓我們看一下mul函數(用於乘法)。 add和sub函數大致相同。
Php::Value add(Php::Parameters ¶ms) { Php::Value t = params[0]; Complex *a = (Complex *) t.implementation(); r += (double) a->getReal(); i += (double) a->getImage(); return this; }
注意:在本文中,我將不介紹一些之前討論過的基本主題,例如修改Makefile和ini文件、註冊成員函數、類和命名空間等。請參考前面的部分了解這些內容。
將this指針從C 返回到PHP很簡單。在這個C 函數內部,this指針(作為Complex *類型)可以作為Php::Value類型返回到PHP。轉換不會丟失任何對象信息。它也不需要顯式類型轉換。
返回Complex對象指針
返回this通常意味著對象本身已更改。但在某些情況下,我們可能希望返回一個新對象並保持“當前”對象(調用對象)不變。
在我們的Complex類中,我們有一個這樣的函數,它返回給定複數的共軛數(a bi變為a-bi)。
Php::Value add(Php::Parameters ¶ms) { Php::Value t = params[0]; Complex *a = (Complex *) t.implementation(); r += (double) a->getReal(); i += (double) a->getImage(); return this; }
這裡的關鍵點是,我們必須使用Php::Object將我們的Complex *對象顯式轉換為Php::Object,因此當該對象稍後由PHP腳本解析時,可以正確保留類信息並保持其可訪問性。
此函數的第一個參數是類類型,在本例中為trComplex。我使用此名稱是因為我已將此類(“Complex”)包裝到單獨的命名空間(“tr”)中。
第二個參數是要傳回的對象。
返回新的類實例比只返回this指針要棘手一些,但只要您閱讀了文檔並找到了正確的部分,仍然是可以管理的。有關更多用法示例,您可能需要閱讀PHP-CPP官方文檔中的這一部分。
公開__toString魔術方法
在我們的類中,有一個__toString
函數,它以更易讀的方式打印複數,例如:1 2i。在我之前的文章中,此函數未公開(或在PHP-CPP術語中“註冊”),但仍然可以從PHP內部調用。但是,為了使此函數在我們應用一些數學運算(例如“echo $a->add($b)->sub($c)”)後能夠在Complex對像上調用,我們需要在已編譯的擴展中顯式註冊它:
Php::Value conjugate() { Complex *t = new Complex(); t->r = r; t->i = -i; return Php::Object("tr\Complex", t); }
我們在PHP-CPP存儲庫中提交的問題Issue #150詳細討論了我們必須這樣做的原因。
鍊式成員函數調用
必須在此類中實現的一件事是能夠鏈接成員函數,以便我們可以進行如下計算:$a->add($b)->sub($c)。結果仍然應該能夠調用其成員函數。
這是通過上述方法完成的,即返回this指針到PHP。但是,較舊的PHP-CPP庫在取消引用對象時存在錯誤,如果鏈接方法調用,則會創建“段錯誤”。
已提交問題(#151),並提交了包含PHP-CPP源代碼補丁的提交。如果您使用的是舊版本的PHP-CPP庫來編譯PHP-CPP庫和您自己的庫,請更新PHP源代碼並重新編譯和重新安裝PHP-CPP庫和您的庫。
如提交摘要所解釋:
complex.method("__toString", &Complex::__toString);
我很高興我自己的項目工作可以幫助我使用的庫變得更好。
異常拋出和PHP中的處理
我們的Complex類中還有兩個函數可能會將異常拋回PHP進行處理:div和phi。前者執行除法運算,後者返回複數的角度,如其替代表示形式極坐標表示法(r,θ)所示。
如果將復數作為參數(或調用者)傳遞,但其實部和虛部為0,則這兩個操作都可能失敗。對於這兩個操作,我們需要進行異常處理。請記住,我們要在C 代碼中拋出異常,而PHP腳本將捕獲異常並進行必要的處理:
Php::Value add(Php::Parameters ¶ms) { Php::Value t = params[0]; Complex *a = (Complex *) t.implementation(); r += (double) a->getReal(); i += (double) a->getImage(); return this; }
在PHP腳本中,我們像這樣捕獲此異常:
Php::Value conjugate() { Complex *t = new Complex(); t->r = r; t->i = -i; return Php::Object("tr\Complex", t); }
上面的代碼段將顯示如下文本行:
complex.method("__toString", &Complex::__toString);
很簡單,對吧?在我們的擴展中構造的C 異常被傳回PHP並被正確捕獲。此外,我們可以像處理其他PHP代碼拋出的原生PHP異常一樣操作異常!
測試所有函數
最後,我們可以通過make && sudo make install
為我們的PHP安裝編譯和安裝complex.so擴展。如果一切順利,我們可以通過在終端中發出以下命令來驗證擴展的安裝:
<code>修复问题#151,链式方法调用无法正常工作…… ……因为每个对象的引用计数未正确更新,这导致即使对象已分配给不同的变量,该对象也会被销毁。</code>
終端應該顯示一行顯示“/etc/php5/cli/conf.d/complex.ini”,我們可以確定我們的擴展已安裝並準備由任何PHP腳本調用。
注意:如果我們檢查此擴展的Makefile,我們將看到我們正在將此PHP擴展安裝到其CLI環境中。如果我們想安裝此擴展以便Apache加載它,我們更改以下行:
Php::Value div(Php::Parameters ¶ms) { Php::Value t = params[0]; Complex *b = (Complex*) t.implementation(); double t1 = b->mod() * b->mod(); if (t1 == 0) throw Php::Exception("Division by zero"); double tr = r * (double) (b->getReal()) + i * (double) (b->getImage()); double ti = i * (double) (b->getReal()) - r * (double) (b->getImage()); r = tr / t1; i = ti / t1; return this; }
此擴展的測試PHP腳本如下所示,並帶有一些註釋:
$a=new tr\Complex(1,2); $c=new tr\Complex(); //$c实际上是0+0i try { $res=$a->div($c); } catch(Exception $e) { echo "Caught exception: ".$e->getMessage()."\n"; } }
所有測試腳本都應該正確運行,並且異常被正確捕獲。
結論
這總結了我關於使用C 構建PHP擴展的這個強大庫的3篇文章系列。我們介紹了基礎知識、面向對象方面以及面向對象編程中的一些高級主題。我們還幫助PHP-CPP有所改進。
我們還能用PHP-CPP做什麼?我將引用幾行我從Emiel Bruijntjes(PHP-CPP的合著者)收到的電子郵件通信:
如果您正在從事一個項目,並且具有以下一個或多個要求,則PHP-CPP庫是理想的選擇: – 您正在處理軟件/數據結構/算法,並且您希望確保將來您的軟件也可以用於非PHP項目。 – 您想使用尚未作為PHP擴展提供的工具或庫。 – 您希望獲得C/C 代碼的更好性能(與PHP相比),但您還想構建結構化、面向對象的代碼,以便其他開發人員/同事易於理解和維護。
可能性是巨大的:框架(如Phalcon)、模板語言(如Smarty或Twig)等等。
請留下您的評論和觀點,讓我們知道您使用此庫做了什麼!
使用C 開發PHP擴展的常見問題解答
使用C 開發PHP擴展的好處是什麼?
使用C 開發PHP擴展具有多種好處。首先,它允許您在PHP應用程序中利用C 的強大功能和靈活性。這可以提高性能,尤其是在計算密集型任務中。其次,它提供了一種在PHP環境中重用現有C 代碼的方法,這可以節省大量的開發時間和精力。最後,它使您能夠創建自定義PHP擴展,這些擴展可以擴展PHP的功能並提供標準PHP庫中不可用的功能。
如何開始使用C 進行PHP擴展開發?
要開始使用C 進行PHP擴展開發,您需要對PHP和C 編程語言都有基本的了解。您還需要安裝PHP開發環境和C 編譯器。安裝這些先決條件後,您可以開始用C 編寫PHP擴展。網上有很多資源可用,包括教程和示例代碼,可以指導您完成此過程。
什麼是PHP-CPP,它如何幫助PHP擴展開發?
PHP-CPP是一個用於使用C 開發PHP擴展的庫。它提供了一組C 類和方法,簡化了編寫PHP擴展的過程。使用PHP-CPP,您可以以更自然和直觀的方式編寫PHP擴展,使用C 熟悉的語法和概念。這可以使開發過程更高效,並且減少錯誤。
我可以將PHP-CPP用於商業項目嗎?
是的,PHP-CPP是開源軟件,可用於個人和商業項目。但是,重要的是要理解,雖然庫本身是免費的,但您可能需要投入時間和資源來學習如何有效地使用它以及維護您的PHP擴展。
使用C 進行PHP擴展開發的一些常見挑戰是什麼,我該如何克服它們?
使用C 進行PHP擴展開發的一些常見挑戰包括正確管理內存、處理錯誤和異常以及PHP和C 之間的接口。可以通過深入了解PHP和C 、使用良好的編程實踐以及利用PHP-CPP提供的功能和工具來克服這些挑戰。
如何調試用C 編寫的PHP擴展?
可以使用標準C 調試工具調試用C 編寫的PHP擴展。此外,PHP-CPP提供了一些可以幫助調試的功能,例如異常處理和錯誤報告。
我可以將PHP-CPP與其他C 庫一起使用嗎?
是的,PHP-CPP可以與其他C 庫一起使用。這使您可以利用PHP擴展中的各種C 功能。
如何提高用C 編寫的PHP擴展的性能?
您可以通過使用高效的算法和數據結構、最大限度地減少內存使用以及優化C 代碼來提高PHP擴展的性能。此外,PHP-CPP提供了一些可以幫助提高性能的功能,例如直接訪問PHP變量和函數。
我可以為PHP-CPP項目貢獻代碼嗎?
是的,PHP-CPP項目是開源的,歡迎社區的貢獻。您可以通過報告錯誤、建議新功能或提交補丁來貢獻代碼。
在哪裡可以找到更多關於使用C 進行PHP擴展開發的資源?
網上有很多資源可用於學習使用C 進行PHP擴展開發。這些資源包括教程、示例代碼、文檔和論壇。此外,PHP-CPP網站提供了大量關於使用該庫的信息和資源。
以上是使用C和PHP-CPP開發PHP擴展:高級的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

會話劫持可以通過以下步驟實現:1.獲取會話ID,2.使用會話ID,3.保持會話活躍。在PHP中防範會話劫持的方法包括:1.使用session_regenerate_id()函數重新生成會話ID,2.通過數據庫存儲會話數據,3.確保所有會話數據通過HTTPS傳輸。

PHP中有四種主要錯誤類型:1.Notice:最輕微,不會中斷程序,如訪問未定義變量;2.Warning:比Notice嚴重,不會終止程序,如包含不存在文件;3.FatalError:最嚴重,會終止程序,如調用不存在函數;4.ParseError:語法錯誤,會阻止程序執行,如忘記添加結束標籤。

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

HTTP請求方法包括GET、POST、PUT和DELETE,分別用於獲取、提交、更新和刪除資源。 1.GET方法用於獲取資源,適用於讀取操作。 2.POST方法用於提交數據,常用於創建新資源。 3.PUT方法用於更新資源,適用於完整更新。 4.DELETE方法用於刪除資源,適用於刪除操作。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

在PHP中,應使用password_hash和password_verify函數實現安全的密碼哈希處理,不應使用MD5或SHA1。1)password_hash生成包含鹽值的哈希,增強安全性。 2)password_verify驗證密碼,通過比較哈希值確保安全。 3)MD5和SHA1易受攻擊且缺乏鹽值,不適合現代密碼安全。

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

箭頭函數在PHP7.4中引入,是短閉包的簡化形式。 1)它們使用=>運算符定義,省略function和use關鍵字。 2)箭頭函數自動捕獲當前作用域變量,無需use關鍵字。 3)它們常用於回調函數和短小計算,提高代碼簡潔性和可讀性。
