PHP 8.5 compiled to WebAssembly. Run PHP in the browser or in Node.js.
npm install @alganet/phasm
calendar, ctype, fileinfo, filter, iconv, mbstring, opcache, pcntl, pdo, pdo_sqlite, sqlite3, tokenizer, zip.
Plus PHP's always-on core: Core, date, hash, json, lexbor, pcre, random, Reflection, SPL, standard, uri.
get_loaded_extensions() is the authority; npm test asserts this list matches
what the binary actually links, so it cannot drift again.
import Phasm from "@alganet/phasm";
const php = await Phasm({
noInitialRun: true,
print: (text) => process.stdout.write(text + "\n"),
printErr: (text) => process.stderr.write(text + "\n"),
});
php.FS.writeFile("/hello.php", `<?php echo "Hello from PHP!\\n"; ?>`);
php.callMain(["hello.php"]);<script src="https://unpkg.com/@alganet/phasm/dist/php.js"></script>
<pre id="output"></pre>
<script>
Phasm({
noInitialRun: true,
print: (text) => document.getElementById("output").textContent += text + "\n",
printErr: (text) => console.error(text),
}).then((php) => {
php.FS.writeFile("/hello.php", '<?php echo "Hello from PHP!\\n"; ?>');
php.callMain(["hello.php"]);
});
</script>Types ship with the package — Phasm, PhasmOptions, PhasmModule and
PhasmFS are all declared, no @types package needed.
import Phasm, { type PhasmModule } from "@alganet/phasm";
const php: PhasmModule = await Phasm({ noInitialRun: true });Phasm() is a factory function that accepts standard Emscripten Module
options and returns a promise that resolves to the initialized module:
| Option | Description |
|---|---|
noInitialRun |
Set true to prevent automatic execution on load. |
arguments |
Array of CLI arguments (e.g. ["script.php"]). |
print(text) |
Callback for stdout output. |
printErr(text) |
Callback for stderr output. |
stdin() |
Callback to provide stdin input. Return null for EOF. |
The resolved module exposes callMain() to run PHP scripts and FS for
filesystem access.
One run per module. The CLI SAPI's main() does full init and shutdown,
so state leaks across repeated callMain() calls on a single instance and it
will eventually crash. Create a fresh module per run.
Phasm uses Emscripten's virtual filesystem. Write PHP files before calling
callMain():
php.FS.writeFile("/app.php", '<?php echo "works"; ?>');
php.FS.writeFile("/data.json", JSON.stringify({ key: "value" }));
php.callMain(["app.php"]);See the Emscripten File System API for the full reference.
A live demo is available at alganet.github.io/phasm.
See CONTRIBUTING.md for build instructions and development guidelines.