Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PHPをブラウザで動かす技術

glassmonenkey
March 24, 2023
2.3k

 PHPをブラウザで動かす技術

PHPerKaigi2023で登壇しました。

https://fortee.jp/phperkaigi-2023/proposal/de0c3936-8780-487b-a9ce-92a8b90da480

WebAssemblyを使ったブラウザで動作させる方法についての解説をしました。
今回の発表を通してデモサイトも作りました。
https://php-play.dev

glassmonenkey

March 24, 2023
Tweet

Transcript

  1. © 2012-2023 BASE, Inc. 1 PHPerKaigi 2023 BASE株式会社 永野 峻輔

    ( @glassmonekey ) PHPをブラウザで動かす技術
  2. © 2012-2023 BASE, Inc. 2 @glassmonekey #phperkaigi このトークの目的 • WebAssembly

    (Wasm) の基本的な理解 • PHPをブラウザ動かすための仕組みを理解
  3. © 2012-2023 BASE, Inc. 3 @glassmonekey #phperkaigi 自己紹介 所属 BASE

    株式会社 BASE BANKチーム Engineering Program Manager 資金調達プロダクト「YELL BANK」の開発責任者やってます。 Go, PHP, Pythonを書きつつ時々データエンジニアも。 趣味 個人開発 最近は日帰り温泉とかも   SNS Twitter: @glassmonekey  Github: https://github.com/glassmonkey 永野 峻輔 (ながの しゅんすけ) 去年のPHP Conferenceにて
  4. © 2012-2023 BASE, Inc. 4 1 2 3 @glassmonekey #phperkaigi

    Wasmとは ブラウザでPHPを動作するデモ PHPを動作させるための技術について 今日話すこと
  5. © 2012-2023 BASE, Inc. 12 @glassmonekey #phperkaigi JavaScript + Wasm

    WebAssembly: How and why https://blog.logrocket.com/webassembly-how-and-why-559b7f96cd71/ WASMはJSの一部の代替え
  6. © 2012-2023 BASE, Inc. 14 @glassmonekey #phperkaigi Figma • パフォーマンス向上

    (約3倍) • もともとはasm.js (C++からコンパイルしたJS)をつかっていた https://www.figma.com/blog/webassembly-cut-figmas-load-time-by-3x/
  7. © 2012-2023 BASE, Inc. 15 @glassmonekey #phperkaigi 1Password • 入力解析部分で主な改善

    • Chromeで最大13倍、Firefoxだと39倍  https://blog.1password.com/1password-x-may-2019-update/
  8. © 2012-2023 BASE, Inc. 16 @glassmonekey #phperkaigi TensorFlow • パフォーマンス向上(約10倍)

    • 機械学習のようなCPUなどのリソースを酷使する場合とは相性が良い https://yashints.dev/blog/2019/12/17/tfjs-wasm
  9. © 2012-2023 BASE, Inc. 18 @glassmonekey #phperkaigi Web Assemblyとは(2回目) Webブラウザを含む実行環境で

    コード実行とコンパクトなコード表現を実現するバイナリ形式 https://developer.mozilla.org/ja/docs/WebAssembly/Concepts
  10. © 2012-2023 BASE, Inc. 19 @glassmonekey #phperkaigi Wasmの特徴 • 移植性

    ◦ 任意の言語でWebAssemblyにbuildできたら良い • セキュア ◦ Runtimeが隔離(Sandbox化)されているのでセキュア WASM Host System WASI API WASM Runtime
  11. © 2012-2023 BASE, Inc. 20 @glassmonekey #phperkaigi Wasmと仕様 • 基本仕様

    ◦ WASM-Core • ブラウザ用仕様 ◦ WASM Web API ◦ WASM JS API • ブラウザ外仕様 ◦ WASI (Web Assembly System Interface) https://webassembly.org/specs/ それぞれ別物!!
  12. © 2012-2023 BASE, Inc. 21 @glassmonekey #phperkaigi WASI(Web Assembly System

    Interface) 任意のシステムで呼び出すための仕様 • 汎用的なランタイムとして活用 ◦ ex) Wasmer, Wasmtime, Cranelift, WAMR • Edgeコンピューティングでの活用 ◦ ex) CloudflareWorkers (Cloudflare), Compute@Edge (Fastly) • K8sでの活用 ◦ ex) proxy-wasm 詳しくは https://bytecodealliance.org/ WASM Host System WASI API WASM Runtime
  13. © 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している
  14. © 2012-2023 BASE, Inc. 25 @glassmonekey #phperkaigi Wordpress/Playground https://developer.wordpress.org/playground/ •

    WordpressをWasmで動くようにしたもの。 • Iframeで展開される • サービスワーカーがリクエストをインターセプト • npmパッケージが公開されるらしい ?
  15. © 2012-2023 BASE, Inc. 27 @glassmonekey #phperkaigi 動作内容(一部抜粋) • initPHPでWasmモジュールを準備

    • runPHPで任意のPHPコードを 実行できるように • startPHPなどはWordpress/playground からvendoringしたもの
  16. © 2012-2023 BASE, Inc. 29 @glassmonekey #phperkaigi 動作内容イメージ(カスタムHook) • PHPコードの状態管理

    ◦ 選択中のPHPランタイム ◦ プレビュー用のコード ◦ プレビュー結果 ◦ 実行中か • startPHPでPHPRuntimeのバージョン選択 • runPHPで任意のPHPコードの実行 ◦ 例えば<? phpinfo(); のようなコード
  17. © 2012-2023 BASE, Inc. 39 @glassmonekey #phperkaigi emscripten https://emscripten.org/ •

    C/C++をWasmにコンパイルできる • ブラウザなどのRuntimeで実行可能にする • LLVM/Clangベースのコンパイラ
  18. © 2012-2023 BASE, Inc. 40 @glassmonekey #phperkaigi emscriptenの利用例(C++) • C++で書いたのでC++かCかどうかの

    判定マクロが必要 • 今回の例では以下の関数を Wasmへの変換時にexport ◦ main関数 ◦ EMSCRIPTEN_KEEPALIVE でアノテーションした関数 https://github.com/glassmonkey/wasm-sample-cpp https://developer.mozilla.org/ja/docs/WebAssembly/C_to_wasm
  19. © 2012-2023 BASE, Inc. 41 @glassmonekey #phperkaigi emscriptenの利用例 (呼び出し) •

    グルーコードも同時に生成される • Wasmロード時にmain関数が実行完了しても Runtimeが終了しないように • ccallというメソッドで呼び出し可能に • exportした関数の呼び出し https://github.com/glassmonkey/wasm-sample-cpp https://developer.mozilla.org/ja/docs/WebAssembly/C_to_wasm JSからの呼び出し コンパイル
  20. © 2012-2023 BASE, Inc. 48 @glassmonekey #phperkaigi (余談)Patch内容の起源 https://github.com/oraoto/pib/pull/52 大半の修正内容の詳細が不明

    Wasm製PlayGroundへのPRが起源 https://oraoto.github.io/pib/ 当てなくてもいい部分はあるかもしれない。
  21. © 2012-2023 BASE, Inc. 50 @glassmonekey #phperkaigi 動作内容(一部抜粋、再掲) • initPHPでWasmモジュールを準備

    • runPHPで任意のPHPコードを 実行できるように • runPHPで任意のPHPコードを 実行できるように • runPHPで任意のPHPコードを 実行できるように • runPHPで任意のPHPコードを 実行できるように • startPHPなどはWordpress/playground からvendoringしたもの
  22. © 2012-2023 BASE, Inc. 51 @glassmonekey #phperkaigi PHPオブジェクトの中身 • Runtimeはコンパイラ経由のグルーコード

    が該当する。 • setPHPCodeとhandleRequstが肝 ?>を先頭につけることで、 前回実行したPHPコードを終了させてい る
  23. © 2012-2023 BASE, Inc. 52 @glassmonekey #phperkaigi Wasm関数の呼び出し • ccallでC側で定義した各種関数をコールしている

    • Wasm上のファイルシステム経由で結果を取得 • ファイルシステム(一部抜粋) ◦ MEMFS(デフォルト) ▪ いわゆるオンメモリ。リロードで消える ◦ NODEFS ▪ nodejsで使用するとき(ローカルで永続化) ◦ IDBFS ▪ ブラウザのIndexedDBを使用する などなど https://emscripten.org/docs/api_reference/Filesystem-API.html#file-s ystems
  24. © 2012-2023 BASE, Inc. 57 @glassmonekey #phperkaigi まとめ • WasmはWebアプリのリッチ化で始まった技術

    • PHPはブラウザでも呼び出し可能 ◦ 永続化方法がブラウザベースだと課題感あり ◦ CloudflareのD1あたりとの組み合わせの可能性はありそう ◦ Playgroundレベルだと実用性あり。ぜひ使ってね!! • PHPのソースコード読むことは楽しい • Wasmの動向は要チェック