Phasis
JavaScript, napisan v PHP: ES2024+ uspešno opravi vse teste 50,506 test262 (posnetek z dne 2025-05-05), poleg tega pa podpira še URL, kodiranje, structuredClone, fetch in Streams.
composer require phasis/phasisNajnovejša izdaja v0.4.2 MIT PHP 8.2+, ext-bcmath, ext-curl, ext-mbstring
./vendor/bin/phasis -e '1 + 2 * 3'
# 7
./vendor/bin/phasis -e '[1, 2, 3].map(x => x * x).join(",")'
# 1,4,9
./vendor/bin/phasis path/to/script.jsV praksi
En objekt mehanizma izvaja JavaScript v procesu PHP in vrednosti posreduje v obe smeri.
Zaženite JavaScript iz PHP
Phasis\Engine vrednoti izvorne nize in datoteke v procesu PHP, ki ga kliče. setGlobal() pretvori polja PHP v polja in objekte JavaScript ter zaprtja PHP ovije kot funkcije.
Izhod console.log se medpomni v mehanizmu in ga preberete z getConsoleOutput(). Oblikovalnik v drugem zavihku ne potrebuje mehanizma.
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"use Phasis\Formatter\Formatter;
use Phasis\Formatter\FormatOptions;
$formatted = Formatter::formatSource(
"const a={x:1,y:2};",
'script',
new FormatOptions(useTabs: true, singleQuote: true),
);
// "const a = { x: 1, y: 2 };\n"Čisto PHP
Brez exec() in FFI, brez Node. Potrebuje PHP 8.2+ z ext-curl, ext-bcmath in ext-mbstring; CI uporablja PHP 8.4 in 8.5.
100% test262
Vse kategorije testov 50,506 iz zbirke testov skladnosti ECMAScript na posnetku z dne 2025-05-05 so uspešno opravljene, brez izpuščenih testov.
Sodobni ECMAScript
Razredi, async/await, generatorji, Symbol, BigInt, Proxy, Temporal, TypedArray in Intl z ext-intl. Polna podpora za ES2024+.
API-ji spletne platforme
URL, TextEncoder in TextDecoder, atob in btoa, structuredClone, performance in DOMException so vgrajeni.
fetch + Streams
Pravi HTTP prek ext-curl iz JS. Polni Fetch API z AbortSignal, Blob, FormData in WHATWG Streams.
Preizkusi spletne platforme
Uvoženi podtesti WPT za fetch, headers, blob, abort, streams in encoding so uspešno opravljeni, razen dovoljenega seznama primerov brotli in SharedArrayBuffer.
PHP ↔ JS: interoperabilnost
setGlobal() izpostavi zaprtja PHP kot funkcije JS, call() pa iz PHP izvaja funkcije JS. Vrednosti se pretvorijo na meji; polja se kopirajo.
Vdeljiv
En razred Engine: eval, execFile, setGlobal, call. Dodajte ga v katerokoli aplikacijo PHP ali CLI.
Omejitev globine klicev
Fiksni sklad klicev z 4,096 okvirji ustavi nenadzorovano rekurzijo z napako InternalError, ki jo je mogoče ujeti.
CLI
bin/phasis zažene datoteko ali izsek -e in izpiše AST z možnostjo --ast. V kloniranem repozitoriju bin/test262 zažene zbirko testov skladnosti.
Referenčni sistem Node.js
Scenariji se preverjajo glede na Node.js (V8). WPT in knjižnični preizkusi se izvajajo v CI ob potisih, ki posežejo v mehanizem; celoten preizkus test262 se zažene na zahtevo, nazadnje 2026-06-09.
Resnične knjižnice
Paketi 204 npm, med njimi acorn, mustache.js, lodash in marked, so preizkušeni; izhod je bajtno enak izhodu Node.
Zakaj Phasis
Brez procesa Node.js
Phasis leksikalno analizira, razčleni in izvede JavaScript v samem PHP, brez klica v exec() za Node in brez FFI. Namesti se kot paket Composer.
fetch pod nadzorom gostitelja
fetch() privzeto uporablja ext-curl. setFetchTransport() zamenja transport, na primer z imitacijo za preizkuse, setFetchPolicy() pa lahko vsako zahtevo zavrne ali preoblikuje, preden jo pošlje.
Časovniki po navideznem času
eval() izprazni čakalno vrsto dogodkov, preden se vrne, ura pa preskoči na naslednji čakajoči časovnik, namesto da bi čakala. Dolgotrajno delujoči gostitelji lahko z tickEventLoop() poganjajo zanko v realnem času.
Vključena razčlenjevalnik in oblikovalnik
Razčlenjevalnik vrne tipizirani AST PHP, ki ga je mogoče izvoziti v ESTree. Oblikovalnik znova izpiše JavaScript, JSON in CSS v postavitvi, združljivi s prettier.
V primerjavi z
Druge možnosti za izvajanje ali obdelavo JavaScript iz aplikacije PHP.
| Orodje | Primerno za | Razlika v primerjavi z Phasis |
|---|---|---|
| Node.js | Primerno zaNode.js izvaja JavaScript v mehanizmu V8 in razrešuje pakete iz map node_modules, zato se odvisnosti npm naložijo po imenu. | Razlika v primerjavi z PhasisKlicanje Node iz PHP doda drugo izvajalno okolje in mejo podprocesa. Phasis se izvaja znotraj PHP, vendar njegov nalagalnik modulov nima razreševanja node_modules ali izvozov package.json, zato je treba pakete npm najprej združiti, na primer z esbuild. |
| V8Js | Primerno zaV8Js vdeluje mehanizem V8 za Google v PHP in izvaja JavaScript v peskovniku, ki ga je mogoče omejiti s časovno in pomnilniško omejitvijo. | Razlika v primerjavi z PhasisV8Js je prevedena razširitev, ki potrebuje knjižnico libv8. Phasis je navaden PHP iz Composer; dokumentacija navaja, da pri kodi, omejeni z razpošiljanjem, deluje približno 100-krat počasneje kot V8. |
| Peast | Primerno zaPeast razčleni JavaScript v AST ESTree v PHP 5.4 in novejšem ter doda prehod po drevesu, poizvedbe z izbirniki in izris. | Razlika v primerjavi z PhasisPhasis potrebuje PHP 8.2. Njegov razčlenjevalnik vrne tipizirane, nespremenljive objekte vozlišč z izvozom ESTree; isti paket lahko tudi izvaja kodo. |
| Prettier | Primerno zaPrettier oblikuje JavaScript, TypeScript, JSX, CSS, HTML, Markdown, YAML in druge ter se namesti iz npm. | Razlika v primerjavi z PhasisOblikovalnik Phasis podpira samo JavaScript, JSON in CSS. Njegove možnosti posnemajo 3.x za prettier, izvaja pa se v PHP brez Node.js. |
Vprašanja in odgovori
Kratki odgovori iz dokumentacije za Phasis.
Composer zahteva PHP 8.2 ali novejši z bcmath, curl in mbstring. intl je priporočljiv za API-je Intl in koledarje Temporal, ki niso ISO, openssl pa za šifriranje AES v crypto.subtle.
Phasis je tolmač, ki prehaja po drevesu, z navideznim strojem za bajtno kodo, ne pa JIT. Dokumentacija navaja približno 100-krat daljši čas izvajanja kot pri V8 za kodo, omejeno z razpošiljanjem; po njihovih besedah ta meja pri vdelavi, na primer za validacijska pravila, le redko igra vlogo.
Ne po imenu. Nalagalnik modulov razrešuje uvoze glede na datotečni sistem, zahteva izrecne končnice datotek in ne podpira node_modules ali izvozov package.json, zato paket združite z orodjem, kot je esbuild, in posredujte združeno datoteko prek Phasis.
Ne. window, document in drevo DOM niso vključeni, prav tako ne globalni elementi Node, kot so process, Buffer in require().
Namesto da bi se izpisal, se medpomni v mehanizmu. Preberite ga z getConsoleOutput() ali getConsoleLines(), medpomnilnik pa izpraznite z clearConsole().
Neujeta izjema se prikaže kot Phasis\Exceptions\JsThrowable. Napake, ki jih sproži sam pogon, na primer branje lastnosti vrednosti null, se prikažejo kot Phasis\Exceptions\TypeError, ReferenceError ali RangeError; vse te napake razširjajo Phasis\Exceptions\RuntimeError. Neveljavna izvorna koda sproži Phasis\Parser\ParseError, Phasis\Exceptions\SyntaxError, ki vsebuje vrstico, stolpec in odmik.
Začnite z vodnikom za začetek, nato preberite referenco API za prestreznike fetch in zanko dogodkov.