目录

使用 Rust (ext-php-rs) 编写 PHP 扩展教程

本教程将指导你如何使用 Rust 语言和 ext-php-rs 框架(版本 0.15.7)开发一个 PHP 扩展。

在开始之前,请确保你的系统中已安装以下组件:

  • Rust: 需要 1.85+ 版本以支持 2024 Edition。
  • PHP: 建议 8.0+ 及其开发头文件(如 php-dev)。
  • Clang: 编译时依赖,用于生成 FFI 绑定。
  • Cargo-PHP (可选): 用于简化扩展的安装与测试。
    cargo install cargo-php
cargo new --lib my_php_extension
cd my_php_extension

在项目的根目录下,Cargo.toml 定义了扩展的元数据、库类型和依赖项。请确保配置如下:

文件:Cargo.toml (配置说明)

[package]
name = "my_php_extension"
version = "0.1.0"
edition = "2024"

+ [lib]
+ crate-type = ["cdylib"]

[dependencies]
+ ext-php-rs = "0.15.7"

最终版 Cargo.toml

[package]
name = "my_php_extension"
version = "0.1.0"
edition = "2024"

[lib]
crate-type = ["cdylib"]

[dependencies]
ext-php-rs = "0.15.7"
  • crate-type = ["cdylib"]: 关键配置,告诉 Rust 编译器生成 C 兼容的动态库。
  • edition = "2024": 使用最新的 Rust 语言特性。

src/lib.rs 中,我们定义要导出的 PHP 函数和模块入口。

文件:src/lib.rs

use ext_php_rs::prelude::*;

#[php_function]
pub fn hello_rust(name: String) -> String {
    format!("Hello {} from Rust!", name)
}

#[php_function]
pub fn add_numbers(a: i32, b: i32) -> i32 {
    a + b
}

#[php_module]
pub fn get_module(module: ModuleBuilder) -> ModuleBuilder {
    module
        .function(wrap_function!(hello_rust))
        .function(wrap_function!(add_numbers))
}
  1. #[php_function]: 此宏将 Rust 函数转换为 PHP 可调用的函数,自动处理字符串、整数等基本类型的转换。
  2. #[php_module]: 定义扩展的入口点,类似于 C 扩展中的 zend_module_entry
  3. 多函数注册: 通过在 ModuleBuilder 上链式调用 .function(wrap_function!(...)) 来注册多个函数。
  4. wrap_function!: 在 ext-php-rs 0.15.7 中,必须使用此宏来正确注册受 #[php_function] 标记的函数。

使用 Cargo 直接编译生成动态库:

cargo build --release

编译完成后,你可以在 target/release/ 目录下找到 libmy_php_extension.so (Linux) 或 my_php_extension.dll (Windows)。

然后在 PHP 中验证:

php -d extension=./target/release/libmy_php_extension.so -r "echo hello_rust('World') . PHP_EOL; echo '5 + 4 = ' . add_numbers(5, 4) . PHP_EOL;"
cargo install cargo-php

如果你安装了 cargo-php,可以一步到位:

# 自动编译并安装到 PHP 扩展目录
cargo php install --release

.so 文件将会保存到 php-config --extension-dir 所在的文件夹:

ls /usr/local/php/lib/php/extensions/no-debug-non-zts-20250925
libmy_php_extension.so

创建一个 test.php 文件:

<?php
// 调用第一个函数
echo hello_rust("World") . PHP_EOL; 
// 输出: Hello World from Rust!

// 调用第二个函数
echo "1 + 2 = " . add_numbers(1, 2) . PHP_EOL;
// 输出: 1 + 2 = 3

运行:

php test.php
  • 性能: Rust 提供的内存安全性可以有效避免 PHP 扩展中常见的内存泄漏和段错误(Segmentation Fault)。