開発ブログ

株式会社Nextatのスタッフがお送りする技術コラムメインのブログ。

電話でのお問合わせ 075-744-6842 ([月]-[金] 10:00〜17:00)

  1. top >
  2. 開発ブログ >
  3. PHP >
  4. PHPからWebAssemblyのバイナリを実行するphp-ext-wasmを試してみる

PHPからWebAssemblyのバイナリを実行するphp-ext-wasmを試してみる

こんにちは、ナカエです。

今回はPHPからWebAssemblyのバイナリを実行するPHPエクステンションphp-ext-wasm(注: experimental)を見つけたのでそれについての記事です。

今回試した環境

  • Mac OS(High Sierra)
  • PHP 7.2.7
  • Rust 1.32.0-nightly

必要なもの

  • Rustツールチェイン
  • Just (Rust製のビルド自動化ツール)

PHPエクステンションの元となるライブラリがRustで書かれているのでRustツールチェインが必要です。また、ビルド処理はRust製のビルド自動化ツールによってJustfileに記述されています。

準備1. Rustツールチェインのインストール

rustupを使ってインストールします。

rustupのインストール

curl https://sh.rustup.rs -sSf | sh

.bashrcの設定

source ~/.cargo/env

rustのnightlyを入れる

rustup install nightly
rustup default nightly

rustupが使いやすすぎて人生がつらい。

※ 安定リリース版のstableでもいけるかもしれませんが試してません。

準備2. Justのインストール

Homebrewを使います。

brew install just

ビルド

PHPエクステンションのビルド

git clone https://github.com/Hywan/php-ext-wasm
cd php-ext-wasm
# Rustのライブラリのビルド
just rust
# PHPエクステンションのビルド
just php

テストコードの実行

composer install
php -d extension=wasm tests/toy.php
// int(42)

リポジトリの構成

これだけだと味気ないのでリポジトリの構成を見てみましょう。

src/

Rustのライブラリのコードが入っています。このライブラリはWASMのバイナリをインスタンス化して関数を呼び出すAPIを公開します。Rust製のWasmインタープリタwasmiに依存しています。

extension/

PHPエクステンションのコード(lib.rs)が入っています。前述のRustのライブラリのAPIをCのAPIを通じてZend Engineから利用できるようにします。 wasmreadbinary, wasmnewinstance, wasminvokeargumentsbuilder, wasminvoke_function などの関数が含まれます。

headers/

php-ext-wasm.hがjust rustによるビルド時に生成されます。 このヘッダファイルはPHPエクステンションのビルド時に利用されます。

lib

PHPエクステンションが公開するローレベルな関数を使いやすくするためのPHPクラス群です。 テストコードで利用されている\WASM\Instanceなどを含みます。

tests

テストコードです。先ほど実行していたtests/toy.phpはこのようになっています。

<?php
require_once dirname(__DIR__) . '/vendor/autoload.php';
$instance = new WASM\Instance(__DIR__ . '/toy.wasm');
$result = $instance->sum(5, 37);
var_dump($result);

WebAssemblyのバイナリであるtests/toy.wasmを読み込み、sumという関数を呼び出しているのがわかります。

tests/toy.wasmファイルの元となっているのはtoy.rsです。

#[no_mangle]
pub extern "C" fn sum(x: i32, y: i32) -> i32 {
    x + y
}

justfileの記述を見るに、just compile-wasm でtests/toy.rsからtests/toy.wasmをビルドしているようですが、wasm-gcなどのツールを別途用意しておく必要があるようです。

まとめ

少し複雑な構成ですが、php-ext-wasmはRustのwasmインタープリタを使って作られたwasmバイナリ用のライブラリをCでラップしたPHPエクステンションということですね。 まだパフォーマンスは計測していないので次回以降試したいと思います。

TOPに戻る