Přejít k obsahu

Phasis

JavaScript engine napsaný v PHP: ES2024+ splňuje všechny testy test262 50,506 (snapshot z 2025-05-05) a nabízí také URL, kódování, structuredClone, fetch a Streams.

Terminál
composer require phasis/phasis

Nejnovější vydání v0.4.2 MIT PHP 8.2+, ext-bcmath, ext-curl, ext-mbstring

V praxi

Jeden objekt engine spouští JavaScript uvnitř procesu PHP a předává hodnoty oběma směry.

Spouštění JavaScript z PHP

Phasis\Engine vyhodnocuje zdrojové řetězce a soubory v procesu PHP, který jej volá. setGlobal() převádí pole PHP na pole a objekty JavaScript a uzávěry PHP obaluje jako funkce.

Výstup console.log se ukládá do vyrovnávací paměti enginu a čte se pomocí getConsoleOutput(). Formátovač na druhé kartě engine vůbec nepotřebuje.

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"

Čisté PHP

Bez exec(), FFI i Node. Vyžaduje PHP 8.2+ s ext-curl, ext-bcmath a ext-mbstring; CI běží na PHP 8.4 a 8.5.

100% test262

Splňuje všechny testy 50 506 ze sady testů shody s ECMAScriptem ve snapshotu z 2025-05-05, ve všech kategoriích a bez vynechaných testů.

Moderní ECMAScript

Třídy, async/await, generátory, Symbol, BigInt, Proxy, Temporal, TypedArray a Intl s ext-intl. Plná podpora ES2024+.

Rozhraní webové platformy

Vestavěné jsou URL, TextEncoder a TextDecoder, atob a btoa, structuredClone, performance a DOMException.

fetch + Streams

Skutečné HTTP z JS přes ext-curl. Plné Fetch API s AbortSignal, Blob, FormData a WHATWG Streams.

Testy webové platformy

Importované podtesty WPT pro fetch, headers, blob, abort, streams a encoding procházejí, s výjimkou případů brotli a SharedArrayBuffer uvedených na seznamu povolených.

PHP ↔ interoperabilita JS

setGlobal() zpřístupňuje uzávěry PHP jako funkce JS a call() spouští funkce JS z PHP. Hodnoty se převádějí na hranici; pole se kopírují.

Lze vložit

Jedna třída Engine: eval, execFile, setGlobal, call. Lze vložit do libovolné aplikace PHP nebo CLI.

Limit hloubky volání

Pevně daný zásobník volání s limitem 4 096 rámců zastaví nekonečnou rekurzi a vyvolá zachytitelnou chybu InternalError.

CLI

bin/phasis spustí soubor nebo úryvek předaný pomocí -e a vypíše AST s --ast. V klonu repozitáře spustí bin/test262 sadu testů shody.

Oracle Node.js

Scénáře se ověřují proti Node.js (V8). WPT a sada testů knihovny se v CI spouštějí při pushích, které mění engine; kompletní testy test262 se spouštějí na vyžádání, naposledy 2026-06-09.

Skutečné knihovny

Testují se balíčky 204 npm, například acorn, mustache.js, lodash a marked; jejich výstup je bajt po bajtu shodný s Node.

Proč Phasis

Bez procesu Node.js

Phasis lexuje, parsuje a spouští JavaScript přímo v PHP, bez volání exec() do Node a bez FFI. Instaluje se jako balíček Composer.

fetch pod kontrolou hostitele

fetch() ve výchozím nastavení používá ext-curl. setFetchTransport() mění přenosovou vrstvu, například za mock v testech, a setFetchPolicy() může každý požadavek před odesláním zamítnout nebo upravit.

Časovače ve virtuálním čase

eval() před návratem vyprázdní smyčku událostí a hodiny přeskočí k dalšímu čekajícímu časovači místo čekání. Dlouhodobě běžící hostitelé mohou smyčku řídit v reálném čase pomocí tickEventLoop().

Parser a formátovač v ceně

Parser vrací typovaný AST PHP, který lze exportovat do ESTree. Formátovač znovu vypisuje JavaScript, JSON a CSS v rozložení kompatibilním s prettier.

Srovnání

Další způsoby spouštění nebo zpracování JavaScript z aplikace PHP.

Phasis ve srovnání s ostatními nástroji
Node.js Vhodné proNode.js spouští JavaScript v enginu V8 a vyhledává balíčky ve složkách node_modules, takže závislosti npm lze načítat podle názvu. Rozdíl oproti PhasisVolání Node z PHP přidává druhé běhové prostředí a hranici podprocesu. Phasis běží uvnitř PHP, ale jeho načítání modulů nepodporuje node_modules ani rozlišení exportů package.json, takže se balíčky npm nejprve sbalí, například pomocí esbuild.
V8Js Vhodné proV8Js vkládá engine V8 od Google do PHP a spouští JavaScript v izolovaném prostředí, jehož běh lze omezit časovým limitem a limitem paměti. Rozdíl oproti PhasisV8Js je kompilované rozšíření, které vyžaduje knihovnu libv8. Phasis je čisté PHP od Composer; jeho dokumentace uvádí, že běží přibližně 100krát rychleji než V8 u kódu omezeného voláním funkcí.
Peast Vhodné proPeast parsuje JavaScript do AST ESTree v PHP 5.4 a novějších verzích a přidává procházení stromu, dotazy pomocí selektorů a vykreslování. Rozdíl oproti PhasisPhasis vyžaduje PHP 8.2. Jeho parser vrací typované objekty uzlů jen pro čtení s exportem ESTree a stejný balíček umí také spouštět kód.
Prettier Vhodné proPrettier formátuje JavaScript, TypeScript, JSX, CSS, HTML, Markdown, YAML a další jazyky a instaluje se z npm. Rozdíl oproti PhasisFormátovač Phasis podporuje pouze JavaScript, JSON a CSS. Jeho možnosti odpovídají 3.x prettier a běží v PHP, bez Node.js.

Otázky a odpovědi

Stručné odpovědi z dokumentace Phasis.

Začněte průvodcem pro začátek a potom si přečtěte referenční příručku API, kde najdete háčky fetch a smyčku událostí.