使用 Rust (ext-php-rs) 编写 PHP 扩展教程
本教程将指导你如何使用 Rust 语言和 ext-php-rs 框架(版本 0.15.7)开发一个 PHP 扩展。
<!--more-->
1. 环境准备
在开始之前,请确保你的系统中已安装以下组件:
- Rust: 需要 1.85+ 版本以支持
2024 Edition。
- PHP: 建议 8.0+ 及其开发头文件(如
php-dev)。
- Clang: 编译时依赖,用于生成 FFI 绑定。
- Cargo-PHP (可选): 用于简化扩展的安装与测试。
cargo install cargo-php
2. 项目配置
创建项目
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 语言特性。
3. 编写核心代码
在 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))
}
关键点解析:
#[php_function]: 此宏将 Rust 函数转换为 PHP 可调用的函数,自动处理字符串、整数等基本类型的转换。
#[php_module]: 定义扩展的入口点,类似于 C 扩展中的 zend_module_entry。
- 多函数注册: 通过在
ModuleBuilder 上链式调用 .function(wrap_function!(...)) 来注册多个函数。
wrap_function!: 在 ext-php-rs 0.15.7 中,必须使用此宏来正确注册受 #[php_function] 标记的函数。
4. 编译与运行
快速编译
使用 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
5. 进阶说明
- 性能: Rust 提供的内存安全性可以有效避免 PHP 扩展中常见的内存泄漏和段错误(Segmentation Fault)。