PHPerKaigi2023で登壇しました。
https://fortee.jp/phperkaigi-2023/proposal/de0c3936-8780-487b-a9ce-92a8b90da480
WebAssemblyを使ったブラウザで動作させる方法についての解説をしました。 今回の発表を通してデモサイトも作りました。 https://php-play.dev
© 2012-2023 BASE, Inc. 1PHPerKaigi 2023BASE株式会社 永野 峻輔 ( @glassmonekey )PHPをブラウザで動かす技術
View Slide
© 2012-2023 BASE, Inc. 2@glassmonekey#phperkaigiこのトークの目的● WebAssembly (Wasm) の基本的な理解● PHPをブラウザ動かすための仕組みを理解
© 2012-2023 BASE, Inc. 3@glassmonekey#phperkaigi自己紹介所属BASE 株式会社 BASE BANKチーム Engineering Program Manager資金調達プロダクト「YELL BANK」の開発責任者やってます。Go, PHP, Pythonを書きつつ時々データエンジニアも。趣味個人開発最近は日帰り温泉とかも SNSTwitter: @glassmonekey Github: https://github.com/glassmonkey永野 峻輔 (ながの しゅんすけ)去年のPHP Conferenceにて
© 2012-2023 BASE, Inc. 4123@glassmonekey#phperkaigiWasmとはブラウザでPHPを動作するデモPHPを動作させるための技術について今日話すこと
© 2012-2023 BASE, Inc. 5Wasm とは
© 2012-2023 BASE, Inc. 6@glassmonekey#phperkaigiWasmとはWebブラウザを含む実行環境でコード実行とコンパクトなコード表現を実現するバイナリ形式https://developer.mozilla.org/ja/docs/WebAssembly/Concepts
© 2012-2023 BASE, Inc. 7@glassmonekey#phperkaigi対応状況https://developer.mozilla.org/ja/docs/WebAssemblyモダンな環境なら基本動く
© 2012-2023 BASE, Inc. 8@glassmonekey#phperkaigi例 (webassembly.sh)Linuxを模倣したものhttps://webassembly.sh
© 2012-2023 BASE, Inc. 9なぜ Wasm なのか
© 2012-2023 BASE, Inc. 10@glassmonekey#phperkaigiWebアプリのリッチ化
© 2012-2023 BASE, Inc. 11@glassmonekey#phperkaigiJavaScriptだけだと辛い● ブラウザゲーム(特に3D)● AR/VR● 画像処理… etc
© 2012-2023 BASE, Inc. 12@glassmonekey#phperkaigiJavaScript + WasmWebAssembly: How and whyhttps://blog.logrocket.com/webassembly-how-and-why-559b7f96cd71/WASMはJSの一部の代替え
© 2012-2023 BASE, Inc. 13@glassmonekey#phperkaigi導入事例から見るWasmhttps://madewithwebassembly.com/
© 2012-2023 BASE, Inc. 14@glassmonekey#phperkaigiFigma● パフォーマンス向上 (約3倍)● もともとはasm.js (C++からコンパイルしたJS)をつかっていたhttps://www.figma.com/blog/webassembly-cut-figmas-load-time-by-3x/
© 2012-2023 BASE, Inc. 15@glassmonekey#phperkaigi1Password● 入力解析部分で主な改善● Chromeで最大13倍、Firefoxだと39倍 https://blog.1password.com/1password-x-may-2019-update/
© 2012-2023 BASE, Inc. 16@glassmonekey#phperkaigiTensorFlow● パフォーマンス向上(約10倍)● 機械学習のようなCPUなどのリソースを酷使する場合とは相性が良いhttps://yashints.dev/blog/2019/12/17/tfjs-wasm
© 2012-2023 BASE, Inc. 17Wasmの特徴
© 2012-2023 BASE, Inc. 18@glassmonekey#phperkaigiWeb Assemblyとは(2回目)Webブラウザを含む実行環境でコード実行とコンパクトなコード表現を実現するバイナリ形式https://developer.mozilla.org/ja/docs/WebAssembly/Concepts
© 2012-2023 BASE, Inc. 19@glassmonekey#phperkaigiWasmの特徴● 移植性○ 任意の言語でWebAssemblyにbuildできたら良い● セキュア○ Runtimeが隔離(Sandbox化)されているのでセキュアWASMHost SystemWASI APIWASM Runtime
© 2012-2023 BASE, Inc. 20@glassmonekey#phperkaigiWasmと仕様● 基本仕様○ WASM-Core● ブラウザ用仕様○ WASM Web API○ WASM JS API● ブラウザ外仕様○ WASI (Web Assembly System Interface)https://webassembly.org/specs/それぞれ別物!!
© 2012-2023 BASE, Inc. 21@glassmonekey#phperkaigiWASI(Web Assembly System Interface)任意のシステムで呼び出すための仕様● 汎用的なランタイムとして活用○ ex) Wasmer, Wasmtime, Cranelift, WAMR● Edgeコンピューティングでの活用○ ex) CloudflareWorkers (Cloudflare), [email protected] (Fastly)● K8sでの活用○ ex) proxy-wasm詳しくは https://bytecodealliance.org/ WASMHost SystemWASI APIWASM Runtime
© 2012-2023 BASE, Inc. 22PHPをブラウザで動かす
© 2012-2023 BASE, Inc. 23@glassmonekey#phperkaigiデモ (https://php-play.dev)デモページ
© 2012-2023 BASE, Inc. 24@glassmonekey#phperkaigiデモのスペックhttps://php-play.dev● リアルタイムPHP Playground● React製● Github Pagesでhosting● PHP 5.6 ~ 8.2のWasmを切り替え可能に● Wordpress/playground から ビルドスクリプトなどをvendoringしている
© 2012-2023 BASE, Inc. 25@glassmonekey#phperkaigiWordpress/Playgroundhttps://developer.wordpress.org/playground/● WordpressをWasmで動くようにしたもの。● Iframeで展開される● サービスワーカーがリクエストをインターセプト● npmパッケージが公開されるらしい ?
© 2012-2023 BASE, Inc. 26@glassmonekey#phperkaigiコード抜粋
© 2012-2023 BASE, Inc. 27@glassmonekey#phperkaigi動作内容(一部抜粋)● initPHPでWasmモジュールを準備● runPHPで任意のPHPコードを実行できるように● startPHPなどはWordpress/playgroundからvendoringしたもの
© 2012-2023 BASE, Inc. 28@glassmonekey#phperkaigi動作内容イメージ(プレビュー部分)● usePHPで任意のPHPコードを実行● 結果をiframeで展開○ sandbox属性でXSS対策
© 2012-2023 BASE, Inc. 29@glassmonekey#phperkaigi動作内容イメージ(カスタムHook)● PHPコードの状態管理○ 選択中のPHPランタイム○ プレビュー用のコード○ プレビュー結果○ 実行中か● startPHPでPHPRuntimeのバージョン選択● runPHPで任意のPHPコードの実行○ 例えば phpinfo(); のようなコード
© 2012-2023 BASE, Inc. 30@glassmonekey#phperkaigiその他秘話についてhttps://zenn.dev/glassmonkey/articles/ae6cadef80c6c4
© 2012-2023 BASE, Inc. 31@glassmonekey#phperkaigi再掲https://php-play.dev
© 2012-2023 BASE, Inc. 32@glassmonekey#phperkaigiGitHub Pagesで動くPHP!!
© 2012-2023 BASE, Inc. 33PHPをブラウザで呼び出す技術
© 2012-2023 BASE, Inc. 34@glassmonekey#phperkaigiPHPをブラウザで呼び出すためには● PHPをWasm用にコンパイル● WasmをJavaScriptから呼び出す
© 2012-2023 BASE, Inc. 35@glassmonekey#phperkaigiPHPをブラウザで呼び出すためには● PHPをWasm用にコンパイル● WasmをJavaScriptから呼び出す
© 2012-2023 BASE, Inc. 36@glassmonekey#phperkaigiPHPは何言語でかれているか?
© 2012-2023 BASE, Inc. 37@glassmonekey#phperkaigiC言語
© 2012-2023 BASE, Inc. 38@glassmonekey#phperkaigiコンパイルの方針● 基本的にはPHPのソースを流用する● 一部Wasm用に書き換える● C言語のコンパイラを利用する
© 2012-2023 BASE, Inc. 39@glassmonekey#phperkaigiemscriptenhttps://emscripten.org/● C/C++をWasmにコンパイルできる● ブラウザなどのRuntimeで実行可能にする● LLVM/Clangベースのコンパイラ
© 2012-2023 BASE, Inc. 40@glassmonekey#phperkaigiemscriptenの利用例(C++)● C++で書いたのでC++かCかどうかの判定マクロが必要● 今回の例では以下の関数をWasmへの変換時にexport○ main関数○ EMSCRIPTEN_KEEPALIVEでアノテーションした関数https://github.com/glassmonkey/wasm-sample-cpphttps://developer.mozilla.org/ja/docs/WebAssembly/C_to_wasm
© 2012-2023 BASE, Inc. 41@glassmonekey#phperkaigiemscriptenの利用例 (呼び出し)● グルーコードも同時に生成される● Wasmロード時にmain関数が実行完了してもRuntimeが終了しないように● ccallというメソッドで呼び出し可能に● exportした関数の呼び出しhttps://github.com/glassmonkey/wasm-sample-cpphttps://developer.mozilla.org/ja/docs/WebAssembly/C_to_wasmJSからの呼び出しコンパイル
© 2012-2023 BASE, Inc. 42@glassmonekey#phperkaigi準備は整った
© 2012-2023 BASE, Inc. 43@glassmonekey#phperkaigiPHPをWasm用にコンパイル
© 2012-2023 BASE, Inc. 44@glassmonekey#phperkaigiPHPをWasm用にコンパイル= エントリーポイントの作成+ Patchを当てる
© 2012-2023 BASE, Inc. 45@glassmonekey#phperkaigiエントリーポイントの作成● PHP本体を呼びつつ、JSから呼び出せるようにしている● zend_eval_stringを呼び出している。
© 2012-2023 BASE, Inc. 46@glassmonekey#phperkaigiPatchを当てる例(その1)常にPDOをbuildに含めるようにしたり
© 2012-2023 BASE, Inc. 47@glassmonekey#phperkaigiPatchを当てる例(その1)空ファイルをfile_get_contentsでJS経由で可能にしたり
© 2012-2023 BASE, Inc. 48@glassmonekey#phperkaigi(余談)Patch内容の起源https://github.com/oraoto/pib/pull/52大半の修正内容の詳細が不明Wasm製PlayGroundへのPRが起源https://oraoto.github.io/pib/当てなくてもいい部分はあるかもしれない。
© 2012-2023 BASE, Inc. 49@glassmonekey#phperkaigiPHPをブラウザで呼び出すためには● PHPをWasm用にコンパイル● WasmをJavaScriptから呼び出す
© 2012-2023 BASE, Inc. 50@glassmonekey#phperkaigi動作内容(一部抜粋、再掲)● initPHPでWasmモジュールを準備● runPHPで任意のPHPコードを実行できるように● runPHPで任意のPHPコードを実行できるように● runPHPで任意のPHPコードを実行できるように● runPHPで任意のPHPコードを実行できるように● startPHPなどはWordpress/playgroundからvendoringしたもの
© 2012-2023 BASE, Inc. 51@glassmonekey#phperkaigiPHPオブジェクトの中身● Runtimeはコンパイラ経由のグルーコードが該当する。● setPHPCodeとhandleRequstが肝?>を先頭につけることで、前回実行したPHPコードを終了させている
© 2012-2023 BASE, Inc. 52@glassmonekey#phperkaigiWasm関数の呼び出し● ccallでC側で定義した各種関数をコールしている● Wasm上のファイルシステム経由で結果を取得● ファイルシステム(一部抜粋)○ MEMFS(デフォルト)■ いわゆるオンメモリ。リロードで消える○ NODEFS■ nodejsで使用するとき(ローカルで永続化)○ IDBFS■ ブラウザのIndexedDBを使用するなどなどhttps://emscripten.org/docs/api_reference/Filesystem-API.html#file-systems
© 2012-2023 BASE, Inc. 53@glassmonekey#phperkaigiC言語側との対応
© 2012-2023 BASE, Inc. 54まとめ
© 2012-2023 BASE, Inc. 55@glassmonekey#phperkaigiまとめブラウザ上でもPHPは動く
© 2012-2023 BASE, Inc. 56@glassmonekey#phperkaigiまとめWasmと仲良くなりましょう
© 2012-2023 BASE, Inc. 57@glassmonekey#phperkaigiまとめ● WasmはWebアプリのリッチ化で始まった技術● PHPはブラウザでも呼び出し可能○ 永続化方法がブラウザベースだと課題感あり○ CloudflareのD1あたりとの組み合わせの可能性はありそう○ Playgroundレベルだと実用性あり。ぜひ使ってね!!● PHPのソースコード読むことは楽しい● Wasmの動向は要チェック
© 2012-2023 BASE, Inc. 58宣伝
© 2012-2022 BASE, Inc. 59#phperkaigi@glassmonkeyhttps://kyloz.wraptas.site/個人開発!!
© 2012-2022 BASE, Inc. 60#phperkaigi@glassmonkeyフルサイクル開発やってます!!Go, Pythonも書いてます!!DM待ってます!!We are hiring !!