在 PHP 裡使用 WASM
前言
相信大家都有聽過 WASM(Webassembly),在很多環境也都已經可以使用 WASM 的模組,最近發現 PHP 也有模組可以支援 WASM 了,是由 wasmer.io 開發,這篇文章分享怎麼安裝及使用 WASM wasmer-php
繼續閱讀前,請先確認環境有安裝編譯器以及 make
目前 wasmer-php 還不支援 PHP 8.0,請使用 PHP 8.0 以下的版本
Mac 的話要用 brew 另外安裝一個 PHP才能編譯,不然會遇到 unsigned extension 的問題
安裝 PHP extension
首先將 repo clone 到本地端
$ git clone https://github.com/web3p/wasmer-php.git
再來編譯並安裝 PHP extension
$ make
如果有使用 just 可以執行
$ just build
安裝完成 wasm.so 會放在 extensions 的目錄下面,如果沒有的話要複製一下
$ cp src/modules/wasm.so PATH_TO_EXTENSION/wasm.so
問題:Call to undefined function Wasm\*
編譯安裝後預設是沒有讀取 wasm 的 extension,可以將 extension=wasm 加進設定檔,或是在執行時加入 -d extension=wasm
接著我們執行測試和 benchmarks 確認是否安裝成功
測試
$ composer test
benchmarks
$ composer bench
使用 WASM
安裝完 extension 後我們可以開始使用 WASM 的 Class 或是 Function
- Class
Int array: WasmInt8Array, WasmInt16Array, WasmInt32Array
Uint array: WasmUint8Array, WasmUint16Array, WasmUint32Array
- Function
wasm_fetch_bytes, wasm_validate, wasm_compile, etc.
更多資訊可以看這份文檔:https://github.com/web3p/wasmer-php/tree/master/lib
或是看原始碼:https://github.com/web3p/wasmer-php/blob/master/src/wasm.cc
如果不想用這些底層的方法可以用這個套件 php-wasm/php-wasm
$ composer require php-wasm/php-wasm
這個套件實做了 Module 跟 Instance(因為 wasm 是 binary 的檔案,所以我們需要 Module 跟 Instance 才能執行裡面的程式)
$module = new Wasm\Module('sum.wasm');
$instance = $module->instantiate();
$result = $instance->sum(1, 2);
或是
$instance = new Wasm\Instance('sum.wasm');
$result = $instance->sum(1, 2);
為什麼會想用 Module 呢?
- Module 可以被 persistent 儲存在 PHP
下面這段程式碼是 wasm_compile 初始化並儲存 Module 的一小段
if (persistent_wasm_module) { resource = zend_register_persistent_resource_ex( resource_key, (void *) wasm_module, wasm_module_resource_number );}
- Module 可以被序列化並儲存在 Cache
原始碼: wasm_module_serialize wasm_module_deserialize
主要是能省下編譯的時間,而編譯的時間則會依照 wasm bytes 有所不同