Phasis
JavaScript dzinis, kas rakstīts PHP: ES2024+ un visi 50 506 test262 testi (2025-05-05 momentuzņēmums), kā arī URL, kodējums, structuredClone, fetch un Streams.
composer require phasis/phasisJaunākais laidiens 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.jsPraksē
Viens dziņa objekts palaiž JavaScript PHP procesā un nodod vērtības abos virzienos.
Palaidiet JavaScript no PHP
Phasis\Engine novērtē avota virknes un failus PHP procesā, kas to izsauc. setGlobal() pārveido PHP masīvus par JavaScript masīviem un objektiem, kā arī aptver PHP noslēgumus kā funkcijas.
console.log izvade tiek buferēta dzinī un nolasīta ar getConsoleOutput(). Otrajā cilnē esošajam formatētājam dzinis nav vajadzīgs.
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"Tīrs PHP
Bez exec(), bez FFI un bez Node. Nepieciešama PHP 8.2+ ar ext-curl, ext-bcmath un ext-mbstring; CI darbojas ar PHP 8.4 un 8.5.
100% test262
Izpilda visus ECMAScript atbilstības kopas 50 506 testus 2025-05-05 momentuzņēmumā, visas kategorijas, bez izlaistiem testiem.
Mūsdienīgs ECMAScript
Klases, async/await, ģeneratori, Symbol, BigInt, Proxy, Temporal, TypedArray un Intl ar ext-intl. Pilns ES2024+.
Tīmekļa platformas API
URL, TextEncoder un TextDecoder, atob un btoa, structuredClone, performance un DOMException ir iebūvēti.
fetch + Streams
Īsts HTTP no JS, izmantojot ext-curl. Pilns Fetch API ar AbortSignal, Blob, FormData un WHATWG Streams.
Web platformas testi
Importētie WPT apakštesti fetch, headers, blob, abort, streams un encoding kategorijām tiek izpildīti, izņemot brotli un SharedArrayBuffer gadījumu atļauto sarakstu.
PHP ↔ JS savietojamība
setGlobal() atklāj PHP noslēgumus kā JS funkcijas, un call() palaiž JS funkcijas no PHP. Vērtības tiek pārveidotas saskarnē; masīvi tiek kopēti.
Iegultams
Viena Engine klase: eval, execFile, setGlobal, call. Iekļaujiet to jebkurā PHP lietotnē vai CLI.
Izsaukumu steka ierobežojums
Fiksēts 4 096 kadru izsaukumu steks aptur nekontrolētu rekursiju ar uztveramu InternalError.
CLI
bin/phasis palaiž failu vai -e fragmentu un izvada AST ar --ast. Repozitorija izrakstā bin/test262 palaiž atbilstības testu kopu.
Node.js etalons
Scenāriji tiek pārbaudīti pret Node.js (V8). WPT un bibliotēkas testu kopa CI tiek palaista, veicot izmaiņas, kas skar dzini; pilnā test262 pārbaude tiek palaista pēc pieprasījuma, pēdējoreiz 2026-06-09.
Reālas bibliotēkas
Tiek testētas 204 npm pakotnes, tostarp acorn, mustache.js, lodash un marked; izvade ir baitu līmenī identiska Node izvadei.
Kāpēc Phasis
Nav Node.js procesa
Phasis veic JavaScript leksisko analīzi, parsēšanu un izpildi PHP, bez exec() izsaukuma uz Node un bez FFI. Tas tiek instalēts kā Composer pakotne.
fetch saimniekdatora vadībā
fetch() pēc noklusējuma izmanto ext-curl. setFetchTransport() ļauj nomainīt transportu, piemēram, pret testu aizstājēju, un setFetchPolicy() var noraidīt vai pārveidot katru pieprasījumu pirms tā nosūtīšanas.
Taimeri virtuālajā laikā
eval() iztukšo notikumu ciklu pirms atgriešanās, un pulkstenis pārlec uz nākamo gaidošo taimeri, nevis nogaida. Ilgstoši darbojošās saimnieklietotnes var darbināt ciklu reāllaikā ar tickEventLoop().
Komplektā ir parsētājs un formatētājs
Parsētājs atgriež tipizētu PHP AST, ko var eksportēt uz ESTree. Formatētājs pārformatē JavaScript, JSON un CSS ar Prettier saderīgu izkārtojumu.
Salīdzinājums ar
Citi veidi, kā palaist vai apstrādāt JavaScript no PHP lietotnes.
| Rīks | Piemērots | Atšķirība no Phasis |
|---|---|---|
| Node.js | PiemērotsNode.js palaiž JavaScript V8 dzinī un meklē pakotnes node_modules mapēs, tāpēc npm atkarības tiek ielādētas pēc nosaukuma. | Atšķirība no PhasisIzsaucot Node no PHP, tiek pievienota otra izpildvide un apakšprocesa robeža. Phasis darbojas PHP, taču tā moduļu ielādētājam nav node_modules vai package.json eksportu atrisināšanas, tāpēc npm pakotnes vispirms jāapvieno, piemēram, ar esbuild. |
| V8Js | PiemērotsV8Js iegulst Google V8 dzini PHP un palaiž JavaScript izolētā vidē, ko var ierobežot ar laika un atmiņas limitiem. | Atšķirība no PhasisV8Js ir kompilēts paplašinājums, kam nepieciešama libv8 bibliotēka. Phasis ir vienkārši PHP no Composer, un tā dokumentācijā norādīts, ka izsaukumu sadales ziņā ierobežotam kodam izpildes laiks ir aptuveni 100 reizes ilgāks nekā V8. |
| Peast | PiemērotsPeast parsē JavaScript par ESTree AST, izmantojot PHP 5.4 vai jaunāku versiju, un nodrošina koka apstaigāšanu, atlasītāju vaicājumus un renderēšanu. | Atšķirība no PhasisPhasis nepieciešama PHP 8.2. Tā parsētājs atgriež tipizētus, tikai lasāmus mezglu objektus ar ESTree eksportu, un tā pati pakotne var arī izpildīt kodu. |
| Prettier | PiemērotsPrettier formatē JavaScript, TypeScript, JSX, CSS, HTML, Markdown, YAML un vēl citus formātus; to var instalēt no npm. | Atšķirība no PhasisPhasis formatētājs atbalsta tikai JavaScript, JSON un CSS. Tā opcijas atbilst Prettier 3.x, un tas darbojas PHP vidē bez Node.js. |
Jautājumi un atbildes
Īsas atbildes no Phasis dokumentācijas.
Composer nepieciešama PHP 8.2 vai jaunāka versija ar bcmath, curl un mbstring. Intl API un kalendāriem, kas nav ISO Temporal, ieteicams intl; AES šifrēšanai crypto.subtle nepieciešams openssl.
Phasis ir koka apstaigāšanas interpretētājs ar baitkoda virtuālo mašīnu, nevis JIT. Dokumentācijā norādīts, ka izsaukumu sadales ziņā ierobežotam kodam izpildes laiks ir aptuveni 100 reizes ilgāks nekā V8; šī maksimālā atšķirība iegulšanas darbos, piemēram, validācijas noteikumos, reti ir būtiska.
Ne pēc nosaukuma. Moduļu ielādētājs importus atrisina, izmantojot failu sistēmu, pieprasa skaidrus failu paplašinājumus un neatbalsta node_modules vai package.json eksportus, tāpēc apvienojiet pakotni ar tādu rīku kā esbuild un padodiet Phasis apvienoto failu.
Nē. Komplektā nav window, document un DOM koka, kā arī nav Node globālo objektu, piemēram, process, Buffer un require().
Tā tiek buferēta dzinī, nevis izvadīta. Nolasiet to ar getConsoleOutput() vai getConsoleLines() un iztukšojiet buferi ar clearConsole().
Neuztverts izņēmums tiek attēlots kā Phasis\Exceptions\JsThrowable. Dzinis radītās kļūdas, piemēram, mēģinājums nolasīt null īpašību, tiek attēlotas kā Phasis\Exceptions\TypeError, ReferenceError vai RangeError, un tās visas paplašina Phasis\Exceptions\RuntimeError. Nederīgs avota kods izraisa Phasis\Parser\ParseError (Phasis\Exceptions\SyntaxError) ar rindas, kolonnas un nobīdes informāciju.
Sāciet ar darba sākšanas rokasgrāmatu, pēc tam lasiet API uzziņu materiālu par fetch āķiem un notikumu ciklu.