完全由 PHP 驱动的 WordPress 完全在浏览器中通过 WebAssembly 运行
当您第一次看到 WordPress Playground 时,它看起来像一个普通的网站,可能除了色彩鲜艳的背景。但它绝非如此。您实际上看到的是整个 WordPress 技术栈,包括 PHP 和数据库,直接在您的浏览器中运行。
在这篇文章中,Adam Zieliński(WordPress Playground 的负责人)和 Thomas Nattestad(V8 的产品经理)将探讨:
- WordPress Playground 如何帮助您作为 WordPress 开发者。
- 其底层工作原理。
- 这对 WordPress 的未来意味着什么。
无需安装即可使用 WordPress,将其嵌入到您的应用程序中,甚至可以使用 JavaScript 控制它
您可以免费使用和自定义嵌入在 playground.wordpress.net 的 WordPress。无需支付云基础设施和支持费用,因为该站点完全存在于您的浏览器中,其他人无法访问它。它也是临时的。一旦您刷新页面,它就会消失。您可以根据需要获取任意数量的此类站点,用于原型设计、试用插件和快速探索想法。
您甚至可以使用它们通过内置的 PHP 和 WordPress 版本切换器在不同的环境中测试您的代码
WordPress Playground 是一种全新的 WordPress 使用方式。然而,只有将其包含在您的应用程序中才能解锁其全部功能。简单的方法是将 WordPress Playground 嵌入到 <iframe>
中,并使用 query parameters API 进行配置。这就是 官方展示 所做的事情。例如,当您选择 Pendant 主题 和 Coblocks 插件 时,嵌入的 iframe 会更新为指向 https://playground.wordpress.net/?theme=pendant&plugin=coblocks。
iframe 是一种简单的入门方式,但也仅限于基本配置选项。如果您需要更多功能,还有另一个更强大的 API。
WordPress Playground JavaScript 客户端可以完全控制嵌入的站点
您可以使用通过 @wp-playground/client npm 包提供的完整 API 来控制整个 WordPress 站点,包括文件系统和 PHP。以下示例展示了如何使用它——查看 交互式教程 以获取更多示例
import {
connectPlayground,
login,
connectPlayground,
} from '@wp-playground/client';
const client = await connectPlayground(
document.getElementById('wp'), // An iframe
{ loadRemote: 'https://playground.wordpress.net/remote.html' },
);
await client.isReady();
// Login the user as admin and go to the post editor:
await login(client, 'admin', 'password');
await client.goTo('/wp-admin/post-new.php');
// Run arbitrary PHP code:
await client.run({ code: '<?php echo "Hi!"; ?>' });
// Install a plugin:
const plugin = await fetchZipFile();
await installPlugin(client, plugin);
即使没有 WordPress 也可以使用 WebAssembly PHP
WordPress Playground 不是一个整体。WebAssembly PHP 与 WordPress 独立发布,您也可以单独使用它。对于 web,您可以使用为低捆绑包大小优化的 @php-wasm/web npm 包,在 Node.js 中,您可以依赖提供更多 PHP 扩展的 @php-wasm/node。Adam 使用前者将交互式 PHP 代码片段添加到 此 WP_HTML_Tag_Processor 教程。以下是如何使用它的快速预览:
import { PHP } from '@php-wasm/web';
const php = await PHP.load('8.0', {
requestHandler: {
documentRoot: '/www',
},
});
// Create and run a script directly
php.mkdirTree('/www');
php.writeFile('/www/index.php', `<?php echo "Hello " . $_POST['name']; ?>`);
php.run({ scriptPath: '/www/index.php' });
// Or use the familiar HTTP concepts:
const response = php.request({
method: 'POST',
relativeUrl: '/index.php',
data: { name: 'John' },
});
console.log(response.text); // Hello John
此时您一定在想——这到底是如何工作的? 好问题!让我们深入了解其内部原理并找出答案。系好安全带!
在底层,有 WebAssembly PHP、SQL 转换器和浏览器内服务器
PHP 作为 WebAssembly 二进制文件运行
PHP 并非开箱即用即可在浏览器中运行。WordPress Playground 开发了一个 专用管道,使用 Emscripten 将 PHP 解释器 构建为 WebAssembly。构建纯 PHP 并非过于复杂——只需 在此处调整函数签名、在那里强制配置变量,并应用 一些小补丁。以下是您自己构建它的方法:
git clone https://github.com/WordPress/wordpress-playground
cd wordpress-playground && npm install
# Below, you can replace "8.2" with any other valid PHP version number.
npm run recompile:php:web:8.2
但是,纯 PHP 构建在浏览器中并不十分有用。作为服务器软件,PHP 没有 JavaScript API 来传递请求正文、上传文件或填充 php://stdin
流。WordPress Playground 不得不从头开始构建一个。WebAssembly 二进制文件附带一个用 C 编写的 专用 PHP API 模块 和一个 JavaScript PHP 类,该类公开了诸如 writeFile()
或 run()
之类的方法。
因为每个 PHP 版本都只是一个静态的 .wasm
文件,所以 PHP 版本切换器实际上非常简单。它只是告诉浏览器下载,例如,php_7_3.wasm
而不是,例如,php_8_2.wasm
。
数据库通过 SQL 转换层提供支持
WordPress 需要 MySQL。但是,没有可以在浏览器中运行的 WebAssembly 版本的 MySQL。因此,WordPress Playground 随 PHP 一起提供了 原生 SQLite 驱动程序,并依赖于 SQLite。
但是 WordPress 如何在不同的数据库上运行呢?
在幕后,官方的 SQLite 数据库集成 插件拦截所有 MySQL 查询,并以 SQLite 方言重写它们。2.0 版本发布了 一个新的 WordPress Playground 知情的翻译层,该翻译层允许 WordPress 在 SQLite 上通过 99% 的 WordPress 单元测试套件。
Web 服务器位于浏览器内部
在常规 WordPress 中,单击链接(例如博客)将发起对远程后端的 HTTP 请求,以获取 blog
页面。但是,WordPress Playground 没有远程后端。它有一个 Service Worker,它拦截所有传出的请求,并将它们传递给在单独的 Web Worker 中运行的浏览器内 PHP 实例。
通过 WebSockets 提供网络支持
在网络方面,WebAssembly 程序仅限于调用 JavaScript API。这既是一项安全功能,也带来了挑战。您如何使用 JavaScript 中可用的高级异步 API 来支持 PHP 使用的低级同步网络代码?
对于 WordPress Playground,答案涉及 WebSocket 到 TCP 套接字代理、Asyncify 以及修补深层 PHP 内部组件(如 php_select
)。这很复杂,但也有回报。面向 Node.js 的 PHP 构建可以请求 web API、安装 composer 包,甚至连接到 MySQL 服务器。
WordPress 可以在比浏览器更多的地方使用
由于 WordPress 现在可以在 WebAssembly 上运行,您也可以在 Node.js 服务器中运行它——它是相同的 V8 引擎!当然,使用 StackBlitz,您也可以直接在浏览器中运行 Node.js,这意味着您可以运行 WordPress 和编译为 WebAssembly 的 PHP,在 Node.js 中执行,Node.js 也被编译为 WebAssembly,在浏览器中运行。WebAssembly 在无服务器领域也越来越受欢迎,将来它也可以在该基础设施上运行。
未来可能会带来零设置、交互式和协作式 WordPress 应用程序
想象一下直接跳转到代码编辑器,您可以立即开始构建,所有设置都已完成。您甚至可以共享一个简单的链接并开始多人编辑会话,例如在 Google Docs 中。当您完成时,只需单击一下即可将您的作品无缝部署到各种托管服务,而无需在本地安装任何东西!
这仅仅是一瞥!我们可能会看到交互式教程、实时插件演示、暂存站点、边缘服务器上的去中心化 WordPress,甚至在您的手机上构建插件。
未来是令人兴奋的,您可以成为其中的一部分!您的想法和贡献是 WordPress Playground 的氧气。访问 GitHub 存储库,在 #meta-playground WordPress.org Slack 频道 中打个招呼,并随时通过 adam@adamziel.com 联系 Adam。