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

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

glassmonenkey
March 24, 2023
1.4k

 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をブラウザで動かす技術

    View Slide

  2. © 2012-2023 BASE, Inc. 2
    @glassmonekey
    #phperkaigi
    このトークの目的
    ● WebAssembly (Wasm) の基本的な理解
    ● PHPをブラウザ動かすための仕組みを理解

    View Slide

  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にて

    View Slide

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

    View Slide

  5. © 2012-2023 BASE, Inc. 5
    Wasm とは

    View Slide

  6. © 2012-2023 BASE, Inc. 6
    @glassmonekey
    #phperkaigi
    Wasmとは
    Webブラウザを含む実行環境で
    コード実行とコンパクトなコード表現を実現するバイナリ形式
    https://developer.mozilla.org/ja/docs/WebAssembly/Concepts

    View Slide

  7. © 2012-2023 BASE, Inc. 7
    @glassmonekey
    #phperkaigi
    対応状況
    https://developer.mozilla.org/ja/docs/WebAssembly
    モダンな環境なら基本動く

    View Slide

  8. © 2012-2023 BASE, Inc. 8
    @glassmonekey
    #phperkaigi
    例 (webassembly.sh)
    Linuxを模倣したもの
    https://webassembly.sh

    View Slide

  9. © 2012-2023 BASE, Inc. 9
    なぜ Wasm なのか

    View Slide

  10. © 2012-2023 BASE, Inc. 10
    @glassmonekey
    #phperkaigi
    Webアプリのリッチ化

    View Slide

  11. © 2012-2023 BASE, Inc. 11
    @glassmonekey
    #phperkaigi
    JavaScriptだけだと辛い
    ● ブラウザゲーム(特に3D)
    ● AR/VR
    ● 画像処理
    … etc

    View Slide

  12. © 2012-2023 BASE, Inc. 12
    @glassmonekey
    #phperkaigi
    JavaScript + Wasm
    WebAssembly: How and why
    https://blog.logrocket.com/webassembly-how-and-why-559b7f96cd71/
    WASMはJSの一部の代替え

    View Slide

  13. © 2012-2023 BASE, Inc. 13
    @glassmonekey
    #phperkaigi
    導入事例から見るWasm
    https://madewithwebassembly.com/

    View Slide

  14. © 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/

    View Slide

  15. © 2012-2023 BASE, Inc. 15
    @glassmonekey
    #phperkaigi
    1Password
    ● 入力解析部分で主な改善
    ● Chromeで最大13倍、Firefoxだと39倍 
    https://blog.1password.com/1password-x-may-2019-update/

    View Slide

  16. © 2012-2023 BASE, Inc. 16
    @glassmonekey
    #phperkaigi
    TensorFlow
    ● パフォーマンス向上(約10倍)
    ● 機械学習のようなCPUなどのリソースを酷使する場合とは相性が良い
    https://yashints.dev/blog/2019/12/17/tfjs-wasm

    View Slide

  17. © 2012-2023 BASE, Inc. 17
    Wasmの特徴

    View Slide

  18. © 2012-2023 BASE, Inc. 18
    @glassmonekey
    #phperkaigi
    Web Assemblyとは(2回目)
    Webブラウザを含む実行環境で
    コード実行とコンパクトなコード表現を実現するバイナリ形式
    https://developer.mozilla.org/ja/docs/WebAssembly/Concepts

    View Slide

  19. © 2012-2023 BASE, Inc. 19
    @glassmonekey
    #phperkaigi
    Wasmの特徴
    ● 移植性
    ○ 任意の言語でWebAssemblyにbuildできたら良い
    ● セキュア
    ○ Runtimeが隔離(Sandbox化)されているのでセキュア
    WASM
    Host System
    WASI API
    WASM Runtime

    View Slide

  20. © 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/
    それぞれ別物!!

    View Slide

  21. © 2012-2023 BASE, Inc. 21
    @glassmonekey
    #phperkaigi
    WASI(Web Assembly System Interface)
    任意のシステムで呼び出すための仕様
    ● 汎用的なランタイムとして活用
    ○ ex) Wasmer, Wasmtime, Cranelift, WAMR
    ● Edgeコンピューティングでの活用
    ○ ex) CloudflareWorkers (Cloudflare), [email protected] (Fastly)
    ● K8sでの活用
    ○ ex) proxy-wasm
    詳しくは https://bytecodealliance.org/ WASM
    Host System
    WASI API
    WASM Runtime

    View Slide

  22. © 2012-2023 BASE, Inc. 22
    PHPをブラウザで動かす

    View Slide

  23. © 2012-2023 BASE, Inc. 23
    @glassmonekey
    #phperkaigi
    デモ (https://php-play.dev)
    デモページ

    View Slide

  24. © 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している

    View Slide

  25. © 2012-2023 BASE, Inc. 25
    @glassmonekey
    #phperkaigi
    Wordpress/Playground
    https://developer.wordpress.org/playground/
    ● WordpressをWasmで動くようにしたもの。
    ● Iframeで展開される
    ● サービスワーカーがリクエストをインターセプト
    ● npmパッケージが公開されるらしい ?

    View Slide

  26. © 2012-2023 BASE, Inc. 26
    @glassmonekey
    #phperkaigi
    コード抜粋

    View Slide

  27. © 2012-2023 BASE, Inc. 27
    @glassmonekey
    #phperkaigi
    動作内容(一部抜粋)
    ● initPHPでWasmモジュールを準備
    ● runPHPで任意のPHPコードを
    実行できるように
    ● startPHPなどはWordpress/playground
    からvendoringしたもの

    View Slide

  28. © 2012-2023 BASE, Inc. 28
    @glassmonekey
    #phperkaigi
    動作内容イメージ(プレビュー部分)
    ● usePHPで任意のPHPコードを実行
    ● 結果をiframeで展開
    ○ sandbox属性でXSS対策

    View Slide

  29. © 2012-2023 BASE, Inc. 29
    @glassmonekey
    #phperkaigi
    動作内容イメージ(カスタムHook)
    ● PHPコードの状態管理
    ○ 選択中のPHPランタイム
    ○ プレビュー用のコード
    ○ プレビュー結果
    ○ 実行中か
    ● startPHPでPHPRuntimeのバージョン選択
    ● runPHPで任意のPHPコードの実行
    ○ 例えば phpinfo(); のようなコード

    View Slide

  30. © 2012-2023 BASE, Inc. 30
    @glassmonekey
    #phperkaigi
    その他秘話について
    https://zenn.dev/glassmonkey/articles/ae6cadef80c6c4

    View Slide

  31. © 2012-2023 BASE, Inc. 31
    @glassmonekey
    #phperkaigi
    再掲
    https://php-play.dev

    View Slide

  32. © 2012-2023 BASE, Inc. 32
    @glassmonekey
    #phperkaigi
    GitHub Pagesで動くPHP!!

    View Slide

  33. © 2012-2023 BASE, Inc. 33
    PHPをブラウザで呼び出す技術

    View Slide

  34. © 2012-2023 BASE, Inc. 34
    @glassmonekey
    #phperkaigi
    PHPをブラウザで呼び出すためには
    ● PHPをWasm用にコンパイル
    ● WasmをJavaScriptから呼び出す

    View Slide

  35. © 2012-2023 BASE, Inc. 35
    @glassmonekey
    #phperkaigi
    PHPをブラウザで呼び出すためには
    ● PHPをWasm用にコンパイル
    ● WasmをJavaScriptから呼び出す

    View Slide

  36. © 2012-2023 BASE, Inc. 36
    @glassmonekey
    #phperkaigi
    PHPは何言語でかれているか?

    View Slide

  37. © 2012-2023 BASE, Inc. 37
    @glassmonekey
    #phperkaigi
    C言語

    View Slide

  38. © 2012-2023 BASE, Inc. 38
    @glassmonekey
    #phperkaigi
    コンパイルの方針
    ● 基本的にはPHPのソースを流用する
    ● 一部Wasm用に書き換える
    ● C言語のコンパイラを利用する

    View Slide

  39. © 2012-2023 BASE, Inc. 39
    @glassmonekey
    #phperkaigi
    emscripten
    https://emscripten.org/
    ● C/C++をWasmにコンパイルできる
    ● ブラウザなどのRuntimeで実行可能にする
    ● LLVM/Clangベースのコンパイラ

    View Slide

  40. © 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

    View Slide

  41. © 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からの呼び出し
    コンパイル

    View Slide

  42. © 2012-2023 BASE, Inc. 42
    @glassmonekey
    #phperkaigi
    準備は整った

    View Slide

  43. © 2012-2023 BASE, Inc. 43
    @glassmonekey
    #phperkaigi
    PHPをWasm用にコンパイル

    View Slide

  44. © 2012-2023 BASE, Inc. 44
    @glassmonekey
    #phperkaigi
    PHPをWasm用にコンパイル
    = エントリーポイントの作成
    + Patchを当てる

    View Slide

  45. © 2012-2023 BASE, Inc. 45
    @glassmonekey
    #phperkaigi
    エントリーポイントの作成
    ● PHP本体を呼びつつ、JSから呼び出せるよう
    にしている
    ● zend_eval_stringを呼び出している。

    View Slide

  46. © 2012-2023 BASE, Inc. 46
    @glassmonekey
    #phperkaigi
    Patchを当てる例(その1)
    常にPDOをbuildに含めるようにしたり

    View Slide

  47. © 2012-2023 BASE, Inc. 47
    @glassmonekey
    #phperkaigi
    Patchを当てる例(その1)
    空ファイルをfile_get_contentsでJS経由で
    可能にしたり

    View Slide

  48. © 2012-2023 BASE, Inc. 48
    @glassmonekey
    #phperkaigi
    (余談)Patch内容の起源
    https://github.com/oraoto/pib/pull/52
    大半の修正内容の詳細が不明
    Wasm製PlayGroundへのPRが起源
    https://oraoto.github.io/pib/
    当てなくてもいい部分はあるかもしれない。

    View Slide

  49. © 2012-2023 BASE, Inc. 49
    @glassmonekey
    #phperkaigi
    PHPをブラウザで呼び出すためには
    ● PHPをWasm用にコンパイル
    ● WasmをJavaScriptから呼び出す

    View Slide

  50. © 2012-2023 BASE, Inc. 50
    @glassmonekey
    #phperkaigi
    動作内容(一部抜粋、再掲)
    ● initPHPでWasmモジュールを準備
    ● runPHPで任意のPHPコードを
    実行できるように
    ● runPHPで任意のPHPコードを
    実行できるように
    ● runPHPで任意のPHPコードを
    実行できるように
    ● runPHPで任意のPHPコードを
    実行できるように
    ● startPHPなどはWordpress/playground
    からvendoringしたもの

    View Slide

  51. © 2012-2023 BASE, Inc. 51
    @glassmonekey
    #phperkaigi
    PHPオブジェクトの中身
    ● Runtimeはコンパイラ経由のグルーコード
    が該当する。
    ● setPHPCodeとhandleRequstが肝
    ?>を先頭につけることで、
    前回実行したPHPコードを終了させてい

    View Slide

  52. © 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

    View Slide

  53. © 2012-2023 BASE, Inc. 53
    @glassmonekey
    #phperkaigi
    C言語側との対応

    View Slide

  54. © 2012-2023 BASE, Inc. 54
    まとめ

    View Slide

  55. © 2012-2023 BASE, Inc. 55
    @glassmonekey
    #phperkaigi
    まとめ
    ブラウザ上でもPHPは動く

    View Slide

  56. © 2012-2023 BASE, Inc. 56
    @glassmonekey
    #phperkaigi
    まとめ
    Wasmと仲良くなりましょう

    View Slide

  57. © 2012-2023 BASE, Inc. 57
    @glassmonekey
    #phperkaigi
    まとめ
    ● WasmはWebアプリのリッチ化で始まった技術
    ● PHPはブラウザでも呼び出し可能
    ○ 永続化方法がブラウザベースだと課題感あり
    ○ CloudflareのD1あたりとの組み合わせの可能性はありそう
    ○ Playgroundレベルだと実用性あり。ぜひ使ってね!!
    ● PHPのソースコード読むことは楽しい
    ● Wasmの動向は要チェック

    View Slide

  58. © 2012-2023 BASE, Inc. 58
    宣伝

    View Slide

  59. © 2012-2022 BASE, Inc. 59
    #phperkaigi
    @glassmonkey
    https://kyloz.wraptas.site/
    個人開発!!

    View Slide

  60. © 2012-2022 BASE, Inc. 60
    #phperkaigi
    @glassmonkey
    フルサイクル開発やってます!!
    Go, Pythonも書いてます!!
    DM待ってます!!
    We are hiring !!

    View Slide