首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

在 PHP 中呼叫 Rust 擴展:從 FFI 到效能微基準完整實錄

     編輯:PHP 綜合知識

動機

Rust 擁有 C 級效能與記憶體安全,透過 cdylib + C Header + PHP 擴展封裝,可將 CPU 密集型邏輯下沉至 Rust,突破 PHP 效能瓶頸。

完整工具鏈

  1. Rust 靜態庫 (.a) + C Header (.h)
  2. C 擴展 (ext/) 鏈接 Rust 庫,暴露 PHP_FUNCTION
  3. PHP 載入 .so 呼叫

步驟一:Rust 庫

// hello_from_rust.rs
#![crate_type = "staticlib"]
#![feature(libc)]
extern crate libc;
use std::ffi::{CStr, CString};

#[no_mangle]
pub extern "C" fn hello_from_rust(name: *const libc::c_char) -> *const libc::c_char {
    let bytes = unsafe { CStr::from_ptr(name).to_bytes() };
    let s = String::from_utf8_lossy(bytes);
    let out = CString::new(format!("Hello from Rust, {}", s)).unwrap();
    out.into_raw() // 呼叫端需釋放
}

// 釋放輔助
#[no_mangle]
pub extern "C" fn rust_free(ptr: *mut libc::c_char) {
    if !ptr.is_null() { unsafe { CString::from_raw(ptr); } }
}
編譯:rustc --crate-type=staticlib hello_from_rust.rs 產生 libhello_from_rust.a。

步驟二:C Header

// hello_from_rust.h
#ifndef HELLO_H
#define HELLO_H
const char* hello_from_rust(const char* name);
void rust_free(char* ptr);
#endif

步驟三:PHP 擴展骨架

cd php-src/ext
./ext_skel --extname=hello_from_rust
cd hello_from_rust
# 複製 .a、.h 到此目錄

config.m4

PHP_ARG_WITH(hello_from_rust, for hello_from_rust support,
[  --with-hello_from_rust Include hello_from_rust support])
if test "$PHP_HELLO_FROM_RUST" != "no"; then
  PHP_SUBST(HELLO_FROM_RUST_SHARED_LIBADD)
  PHP_ADD_LIBRARY_WITH_PATH(hello_from_rust, ., HELLO_FROM_RUST_SHARED_LIBADD)
  PHP_NEW_EXTENSION(hello_from_rust, hello_from_rust.c, $ext_shared)
fi

hello_from_rust.c

#include "php.h"
#include "hello_from_rust.h"

PHP_FUNCTION(confirm_hello_from_rust_compiled) {
    char *arg = NULL; size_t arg_len;
    if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) return;

    char *rust_str = hello_from_rust("Jared (from PHP!!)");
    php_printf("%s\n", rust_str);
    rust_free(rust_str);

    RETURN_STR(STR_COPY(zend_string_init("OK", 2, 0)));
}

步驟四:編譯安裝

phpize
./configure --with-hello_from_rust
make
sudo make install
# 在 php.ini 加入 extension=hello_from_rust.so

步驟五:驗證

<?php
if (!extension_loaded('hello_from_rust')) dl('hello_from_rust.' . PHP_SHLIB_SUFFIX);
confirm_hello_from_rust_compiled('test');
// 輸出:Hello from Rust, Jared (from PHP!!)
// 返回:OK
?>

效能微基準:斐波那契數列 (n=92)

實作耗時 (100,000 次)相對速度
PHP 純陣列迴圈2.05 秒1.0x
Rust 靜態庫 + PHP 擴展0.59 秒3.5x

Rust 版本約 3.5 倍 於 PHP 純實作,證明下沉 CPU 密集邏輯到 Rust 顯著提升吞吐。

關鍵避坑指南

  1. 記憶體所有權:Rust 回傳 *const c_char 需提供 rust_free,PHP 端用完必須釋放,否則洩漏。
  2. Panic 邊界:Rust panic! 會終止進程,使用 std::panic::catch_unwind 包裝對外函數,轉為錯誤碼返回。
  3. 線程安全:PHP-FPM 多進程,Rust 庫需 Send + Sync 或使用 lazy_static 全域狀態加鎖。
  4. 編譯優化:rustc -C opt-level=3 -C lto=yes 釋放最大效能。
  5. 替代方案:PHP 8.1+ FFI 可直接載入 .so 呼叫 Rust 函數,無需撰寫 C 擴展,但呼叫開銷略高。

結語

Rust + PHP 混合編程讓你在保持 PHP 開發效率的同時,為關鍵路徑注入 C 級效能。適合影像處理、加密、壓縮、科學計算等 CPU 密集場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved