wasmer/wasmer-php 是唯一成熟且可通过 Composer 集成的 PHP 调用 WebAssembly 方案,基于 C++ 编写的 Wasmer 运行时,支持 WASI、LLVM/JIT,需 Rust 导出 C ABI 函数并编译为 wasm32-wasi 目标。

PHP 本身不能直接加载或执行 .wasm 文件,必须依赖外部运行时。目前唯一成熟、可直接通过 Composer 集成的方案是 wasmer/wasmer-php —— 它不是“PHP 原生”实现,而是 PHP 扩展级绑定,底层调用 Wasmer 运行时(C++ 编写),性能和稳定性远超纯用户态模拟器。
为什么不用 php-wasm 或其他纯 JS/PHP 模拟方案
像 php-wasm 这类 npm 包本质是让 PHP 代码跑在 WASM 里(反向集成),不解决“PHP 调用 WASM”的问题;而纯 PHP 实现的 WASM 解释器(如某些实验性库)既无 JIT、也不支持 WASI,连 fibonacci(40) 都会卡死。真实项目中,你真正需要的是:低开销、支持 WASI、能调用 Rust/C 编译出的生产级模块。
-
wasmer/wasmer-php直接复用 Wasmer 2.x 的 LLVM/JIT 后端,函数调用延迟通常 - 它要求 PHP 8.1+ + ZTS(线程安全)编译,且必须启用
extension=wasmer.so - 不兼容 Alpine Linux 的 musl libc(除非自己编译 Wasmer 静态链接版)
安装与初始化的关键三步
跳过全局扩展编译,用 Composer + 预编译二进制是最稳妥的落地方式:
- 执行
composer require wasmer/wasmer-php:^3.0(注意:v3 是当前唯一支持 PHP 8.3+ 和 WASI 的版本) - 下载对应平台的
wasmer-runtime二进制(Linux x86_64 / macOS ARM64 官方提供预编译包),放至vendor/bin/wasmer - 初始化时必须显式传入
WASI配置,否则file_read等系统调用直接 panic:$store = new \Wasmer\Store(); $module = new \Wasmer\Module($store, file_get_contents('math.wasm')); $instance = new \Wasmer\Instance($module, [ 'wasi_snapshot_preview1' => \Wasmer\Wasi::default() ]);
从 Rust 编译到 PHP 调用的完整链路
Rust 源码必须导出 C ABI 函数,且禁用 panic 展开(否则 PHP 进程会 segfault):
立即学习“PHP免费学习笔记(深入)”;
- Rust 中用
#[no_mangle]+extern "C",返回值统一为i32或u32(PHP 不识别Result) - 编译命令必须加
--target wasm32-wasi(不是wasm32-unknown-unknown),否则无法启用 WASI 文件/网络能力 - PHP 调用前,先检查导出函数是否存在:
$instance->exports->has('is_prime'),避免Call to undefined method - 传参时注意:WASM 内存是线性的,字符串需先写入实例内存再传指针 ——
wasmer-php不自动处理字符串 marshalling,这是最容易 crash 的点
真正难的不是调用,而是错误定位:WASM 模块崩溃时 PHP 只报 Segmentation fault,没有堆栈。必须用 wasmer inspect math.wasm 查看导出表,并在 Rust 侧加 panic=abort 编译选项来强制生成可读错误信息。



















