ブラウザタブが実行を調整します
メインのindex.htmlはアプリケーション全体をまとめる役割を果たします。すべての同時プロセスを起動し、PHPレスポンスを表示します。アプリケーション はメインのindex.htmlが存在する限り有効です。
残りのドキュメントを読む際には、この点に留意してください。この時点では明らかなように思えるかもしれませんが、後々分かりにくくなる可能性があります。このパッケージは、Web Worker、Service Worker、そして将来的には Shared Worker を使用して、ブラウザタブの外でコードを実行します。これらの Worker の一部は、index.html を含むブラウザタブが閉じられた後も実行され続ける可能性があります。
ブートシーケンス
最小限のアプリのブート シーケンスは次のようになります。

メインアプリは、iframe、サービスワーカー、そしてワーカースレッドを起動します。メインアプリはPHPスタックを直接使用していないことに注意してください。すべてワーカースレッドで処理されます。
ブート シーケンスをコードで表すと次のようになります。
/index.html:
<script src="/app.ts"></script>
<iframe id="my-app"></iframe>
/app.ts:
import { consumeAPI, PHPClient, registerServiceWorker, spawnPHPWorkerThread } from '@php-wasm/web';
const workerUrl = '/worker-thread.js';
export async function startApp() {
const phpClient = consumeAPI<PlaygroundWorkerEndpoint>(
await spawnPHPWorkerThread(
workerUrl, // Valid Worker script URL
{
wpVersion: 'latest',
phpVersion: '8.3', // Startup options
}
)
);
// Await the two-way communication channel
await phpClient.isReady();
// Must point to a valid Service Worker script:
await registerServiceWorker(
phpClient,
'default', // PHP instance scope, keep reading to learn more.
'/sw.js', // Valid Service Worker script URL.
'1' // Service worker version, used for reloading the script.
);
// Create a few PHP files to browse:
await workerThread.writeFile('/index.php', '<a href="page.php">Go to page.php</a>');
await workerThread.writeFile('/page.php', '<?php echo "Hello from PHP!"; ?>');
// Navigate to index.php:
document.getElementById('my-app').src = playground.pathToInternalUrl('/index.php');
}
startApp();
これらすべての要素がどのように組み合わさるのかを学ぶために読み続けてください。
データフロー
iframe が同じドメインのリクエストを発行するたびに、次のことが起こります。

ステップごとの内訳:
- リクエストはサービスワーカーによってインターセプトされます。
- サービスワーカーはリクエストをワーカースレッドに渡します。
- ワーカースレッドはリクエストをレスポンスに変換するために
PHP.requestを呼び出します。 - ワーカースレッドはレスポンスをサービスワーカーに渡します。
- サービスワーカーはブラウザにレスポンスを提供します。
この時点で、ユーザーがリンクをクリックしてリクエストがトリガーされた場合、ブラウザは PHPRequestHandler の応答を iframe 内にレンダリングします。