本篇文章跟大家介紹一下能夠讓PHP能夠呼叫C的函數:FFI擴充。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。
在大型公司中,一般會有很我程式語言的配合。比方說讓 Java 來做微服務層,用 C 來進行底層運算,用 PHP 來做中間層,最後再用 JS 展現效果。這些語言間的配合大部分都是透過 RPC 來完成,或是直接將資料入庫再使用不同的語言來取用。那麼,我們 PHP 的程式碼能否直接呼叫這些語言呢?其實,PHP 還真為我們準備了一個可以直接呼叫 C 語言的擴充函式庫,而這個擴充函式庫還是已經預設內建在 PHP 裡了,它就是 FFI 擴充功能。
什麼是 FFI
FFI , Foreign Function Interface,外部函數介面。這個擴充允許我們載入一些公共函式庫(.dll、.so),其實也就是可以呼叫一些 C 的資料結構及函數。它已經是隨 PHP 原始碼發布的擴充功能了,在編譯的時候可以加上 --with-ffi 來直接編譯到 PHP 程式中。
我們這裡已經是編譯好的 PHP ,所以我們直接找到這個擴展,進行簡單的擴展安裝步驟就可以安裝完成。
cd php-7.4.4/ext/ffi/ phpize ./configure make && make install
安裝完成後記得在 php.ini 檔案中開啟擴充功能。關於這個擴充功能需要注意的一點是,它有一個配置項為 ffi.enable ,預設情況下這個配置項的值是 "preload" ,僅在 CLI SAPI 環境下啟用 FFI 的能力。當然,我們也可以修改為 "true" 或 "false" 來開啟和關閉它。設定為 "true" 將使得這個擴充在任何環境下都啟用。
使用 FFI 呼叫 C 的函數
接下來,簡單地看一下它是如何呼叫 C 的函數的。
// 创建一个 FFI 对象,加载 libc 并且导入 printf 函数 $ffi_printf = FFI::cdef( "int printf(const char *format, ...);", // C 的定义规则 "libc.so.6"); // 指定 libc 库 // 调用 C 的 printf 函数 $ffi_printf->printf("Hello %s!\n", "world"); // Hello World // 加载 math 并且导入 pow 函数 $ffi_pow = FFI::cdef( "double pow(double x, double y);", "libboost_math_c99.so.1.66.0"); // 这里调用的是 C 的 pow 函数,不是 PHP 自己的 echo $ffi_pow->pow(2,3), PHP_EOL; // 8
我們建立了兩個對象,分別呼叫了 C 的 printf() 和 pow() 函數。 FFI::cdef() 是用來建立一個 FFI 對象,它接收兩個參數,一個是包含常規C語言(型別、結構、函數、變數等)宣告序列的字串。
實際上,這個字串可以從C頭檔複製貼上。而另一個參數則是要載入並定義連結的共享庫檔案的名稱。也就是我們需要的.dll 或.so 文件,它與我們宣告字串是對應的,例如在libc.so.6 中並沒有pow() 這類的計算函數,所以我們就要找到math 相關的C語言計算函數庫。
定義變數和陣列
當然,FFI 也是可以定義變數和陣列的。
// 创建一个 int 变量 $x = FFI::new("int"); var_dump($x->cdata); // int(0) // 为变量赋值 $x->cdata = 5; var_dump($x->cdata); // int(5) // 计算变量 $x->cdata += 2; var_dump($x->cdata); // int(7) // 结合上面的两个 FFI 对象操作 echo "pow value:", $ffi_pow->pow($x->cdata, 3), PHP_EOL; // pow value:343 $ffi_printf->printf("Int Pow value is : %f\n", $ffi_pow->pow($x->cdata, 3)); // Int Pow value is : 343.000000 // 创建一个数组 $a = FFI::new("long[1024]"); // 为数组赋值 for ($i = 0; $i < count($a); $i++) { $a[$i] = $i; } var_dump($a[25]); // int(25) $sum = 0; foreach ($a as $n) { $sum += $n; } var_dump($sum); // int(523776) var_dump(count($a)); // int(1024) 数组长度 var_dump(FFI::sizeof($a)); // int(8192),内存大小
使用 FFI::new() 函數來建立一個 C 的資料結構,也就是變數聲明,這些變數的內容將會保存在 cdata 屬性中。而數組則直接就可以操作這個函數的回傳值。當然,當我們要結束使用的時候,還是需要使用 FFI::free() 來釋放變數的,就和 C 語言的開發一樣。
總結
是不是感覺很高大上?但請注意哦,FFI 呼叫的 C 函數並沒有 PHP 本身去呼叫的效率高。例如這種 pow() 函數,使用 PHP 本身的效率更好。而且,FFI 擴展雖說已經是跟隨 PHP 同步發布的擴展,但它還是處於實驗性質的。也就是說,這個擴充是為未來可能用到的其它功能準備的,而且還有很多不確定性。所以在生產環境中如果需要合適類似的功能的話,那就還是要做更多的深入研究哦。
測試程式碼:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202004/source/%E8%AE%A9PHP%E8%83%BD%E5%A4%9F%E8%B0%83%E7%94%A8C%E7%9A%84%E5%87%BD%E6%95%B0-FFI%E6%89%A9%E5%B1%95.php
推薦學習:php影片教學
#以上是讓PHP能夠呼叫C的函數:FFI擴充(附程式碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本文比較了酸和基本數據庫模型,詳細介紹了它們的特徵和適當的用例。酸優先確定數據完整性和一致性,適合財務和電子商務應用程序,而基礎則側重於可用性和

本文討論了確保PHP文件上傳的確保,以防止諸如代碼注入之類的漏洞。它專注於文件類型驗證,安全存儲和錯誤處理以增強應用程序安全性。

本文討論了在PHP中實施API速率限制的策略,包括諸如令牌桶和漏水桶等算法,以及使用Symfony/Rate-limimiter之類的庫。它還涵蓋監視,動態調整速率限制和手

本文討論了使用password_hash和pyspasswify在PHP中使用密碼的好處。主要論點是,這些功能通過自動鹽,強大的哈希算法和SECH來增強密碼保護

本文討論了OWASP在PHP和緩解策略中的十大漏洞。關鍵問題包括注射,驗證損壞和XSS,並提供用於監視和保護PHP應用程序的推薦工具。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

Dreamweaver CS6
視覺化網頁開發工具

WebStorm Mac版
好用的JavaScript開發工具

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

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