# 使用 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 (可选)**: 用于简化扩展的安装与测试。
    ```bash
    cargo install cargo-php
    ```

## 2. 项目配置

### 创建项目
```bash
cargo new --lib my_php_extension
cd my_php_extension
```

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

**文件：`Cargo.toml` (配置说明)**
```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`**
```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`**
```rust
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]` 标记的函数。

## 4. 编译与运行

### 快速编译
使用 Cargo 直接编译生成动态库：
```bash
cargo build --release
```
编译完成后，你可以在 `target/release/` 目录下找到 `libmy_php_extension.so` (Linux) 或 `my_php_extension.dll` (Windows)。

然后在 PHP 中验证：

### 快速单行测试
```bash
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;"
```

### 安装与测试
```bash
cargo install cargo-php
```

如果你安装了 `cargo-php`，可以一步到位：
```bash
# 自动编译并安装到 PHP 扩展目录
cargo php install --release
```

`.so` 文件将会保存到 `php-config --extension-dir` 所在的文件夹：
```bash
ls /usr/local/php/lib/php/extensions/no-debug-non-zts-20250925
libmy_php_extension.so
```

### 使用测试脚本
创建一个 `test.php` 文件：
```php
<?php
// 调用第一个函数
echo hello_rust("World") . PHP_EOL; 
// 输出: Hello World from Rust!

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

运行：
```bash
php test.php
```

## 5. 进阶说明

*   **性能**: Rust 提供的内存安全性可以有效避免 PHP 扩展中常见的内存泄漏和段错误（Segmentation Fault）。

