Lewati ke konten

Phasis

Engine JavaScript yang ditulis dalam PHP: lulus semua tes 50.506 test262 ES2024+ (snapshot 2025-05-05), ditambah URL, encoding, structuredClone, fetch, dan Streams.

Terminal
composer require phasis/phasis

Rilis terbaru v0.4.2 MIT PHP 8.2+, ext-bcmath, ext-curl, ext-mbstring

Dalam praktik

Satu objek engine menjalankan JavaScript di dalam proses PHP dan meneruskan nilai ke kedua arah.

Jalankan JavaScript dari PHP

Phasis\Engine mengevaluasi string sumber dan file dalam proses PHP yang memanggilnya. setGlobal() mengubah array PHP menjadi array dan objek JavaScript, serta membungkus closure PHP sebagai fungsi.

Keluaran console.log disangga di engine dan dibaca kembali dengan getConsoleOutput(). Formatter di tab kedua sama sekali tidak memerlukan engine.

Engine
use Phasis\Engine;

$engine = new Engine();

// Evaluate an expression
$engine->eval('1 + 2 * 3');                  // 7

// Run a file
$engine->execFile('/path/to/script.js');

// Bridge a PHP value into JS (arrays are copied)
$engine->setGlobal('config', ['debug' => true]);
$engine->eval('config.debug');               // true

// console.log is buffered, not printed
$engine->eval('console.log("hi")');
echo $engine->getConsoleOutput();            // hi

// Expose a PHP closure as a JS function
$engine->setGlobal('greet', fn(string $name) => "Hello, $name");
$engine->eval('greet("world")');             // "Hello, world"

PHP Murni

Tanpa exec(), tanpa FFI, tanpa Node. Memerlukan PHP 8.2+ dengan ext-curl, ext-bcmath, dan ext-mbstring; CI menjalankan PHP 8.4 dan 8.5.

100% test262

Lulus seluruh 50.506 tes rangkaian uji kesesuaian ECMAScript pada snapshot 2025-05-05, di setiap kategori tanpa ada yang dilewati.

ECMAScript Modern

Class, async/await, generator, Symbol, BigInt, Proxy, Temporal, TypedArray, dan Intl dengan ext-intl. ES2024+ lengkap.

API Platform Web

URL, TextEncoder dan TextDecoder, atob dan btoa, structuredClone, performance, serta DOMException sudah tersedia secara bawaan.

fetch + Streams

HTTP sungguhan dari JS melalui ext-curl. Fetch API lengkap dengan AbortSignal, Blob, FormData, dan WHATWG Streams.

Tes Platform Web

Subtes WPT yang diimpor untuk fetch, headers, blob, abort, streams, dan encoding lulus, kecuali kasus brotli dan SharedArrayBuffer yang masuk daftar izin.

Interop PHP ↔ JS

setGlobal() mengekspos closure PHP sebagai fungsi JS, dan call() menjalankan fungsi JS dari PHP. Nilai dikonversi pada batas; array disalin.

Dapat disematkan

Satu class Engine: eval, execFile, setGlobal, call. Sematkan di aplikasi PHP atau CLI mana pun.

Batas Call Stack

Call stack tetap sebanyak 4.096 frame menghentikan rekursi tak terkendali dengan InternalError yang dapat ditangkap.

CLI

bin/phasis menjalankan file atau cuplikan -e dan mencetak AST dengan --ast. Dalam checkout repositori, bin/test262 menjalankan rangkaian uji kesesuaian.

Oracle Node.js

Skenario diperiksa terhadap Node.js (V8). WPT dan rangkaian uji library dijalankan di CI pada push yang menyentuh engine; uji test262 lengkap dijalankan sesuai kebutuhan, terakhir pada 2026-06-09.

Library Sungguhan

Sebanyak 204 paket npm, termasuk acorn, mustache.js, lodash, dan marked, diuji dengan keluaran yang identik byte demi byte dengan Node.

Mengapa Phasis

Tanpa proses Node.js

Phasis melakukan leksing, parsing, dan eksekusi JavaScript di dalam PHP itu sendiri, tanpa panggilan exec() ke Node dan tanpa FFI. Instalasinya berupa paket Composer.

fetch dikendalikan host

fetch() menggunakan ext-curl secara default. setFetchTransport() mengganti transport, misalnya dengan mock untuk pengujian, dan setFetchPolicy() dapat menolak atau menulis ulang setiap permintaan sebelum dikirim.

Timer berdasarkan waktu virtual

eval() menguras event loop sebelum kembali, dan jam melompat ke timer tertunda berikutnya alih-alih menunggu. Host yang berjalan lama dapat menggerakkan loop dalam waktu nyata dengan tickEventLoop().

Parser dan formatter sudah disertakan

Parser mengembalikan AST PHP bertipe yang dapat diekspor ke ESTree. Formatter mencetak ulang JavaScript, JSON, dan CSS dengan tata letak yang kompatibel dengan prettier.

Dibandingkan dengan

Cara lain untuk menjalankan atau memproses JavaScript dari aplikasi PHP.

Phasis dibandingkan dengan alat lainnya
Node.js KeunggulanNode.js menjalankan JavaScript di engine V8 dan menyelesaikan paket dari folder node_modules, sehingga dependensi npm dimuat berdasarkan nama. Perbedaan dengan PhasisMemanggil Node dari PHP menambahkan runtime kedua dan batas subprocess. Phasis berjalan di dalam PHP, tetapi pemuat modulnya tidak memiliki node_modules atau resolusi ekspor package.json, sehingga paket npm harus dibundel lebih dulu, misalnya dengan esbuild.
V8Js KeunggulanV8Js menyematkan engine V8 milik Google di PHP dan menjalankan JavaScript dalam sandbox yang dapat dibatasi dengan batas waktu dan memori. Perbedaan dengan PhasisV8Js adalah ekstensi terkompilasi yang memerlukan library libv8. Phasis adalah PHP murni dari Composer, dan dokumentasinya menyebut waktu jalan sekitar 100 kali waktu V8 pada kode yang dibatasi dispatch.
Peast KeunggulanPeast mengurai JavaScript menjadi AST ESTree pada PHP 5.4 dan versi lebih baru, serta menyediakan traversal tree, kueri selector, dan rendering. Perbedaan dengan PhasisPhasis memerlukan PHP 8.2. Parsernya mengembalikan objek node bertipe yang hanya dapat dibaca dengan ekspor ESTree, dan paket yang sama juga dapat menjalankan kode.
Prettier KeunggulanPrettier memformat JavaScript, TypeScript, JSX, CSS, HTML, Markdown, YAML, dan lainnya, serta diinstal dari npm. Perbedaan dengan PhasisFormatter Phasis hanya mendukung JavaScript, JSON, dan CSS. Opsinya mengikuti prettier 3.x dan berjalan di PHP, tanpa Node.js.

Tanya jawab

Jawaban singkat dari dokumentasi Phasis.

Mulailah dengan panduan memulai, lalu baca referensi API untuk hook fetch dan event loop.