Zum Inhalt springen

Phasis

Eine JavaScript-Engine in PHP: ES2024+ besteht alle 50,506 test262-Tests (Snapshot vom 2025-05-05) sowie URL, Encoding, structuredClone, fetch und Streams.

Terminal
composer require phasis/phasis

Neueste Version v0.4.2 MIT PHP 8.2+, ext-bcmath, ext-curl, ext-mbstring

In der Praxis

Ein Engine-Objekt führt JavaScript im PHP-Prozess aus und übergibt Werte in beide Richtungen.

JavaScript aus PHP ausführen

Phasis\Engine wertet Quelltext-Strings und Dateien im PHP-Prozess aus, der es aufruft. setGlobal() wandelt PHP-Arrays in JavaScript-Arrays und -Objekte um und verpackt PHP-Closures als Funktionen.

Die Ausgabe von console.log wird in der Engine gepuffert und mit getConsoleOutput() ausgelesen. Der Formatter im zweiten Tab benötigt keine 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"

Reines PHP

Kein exec(), kein FFI, kein Node. Erfordert PHP 8.2+ mit ext-curl, ext-bcmath und ext-mbstring; CI läuft mit PHP 8.4 und 8.5.

100% test262

Besteht alle 50.506 Tests der ECMAScript-Konformitätssuite im Snapshot vom 2025-05-05, in jeder Kategorie und ohne ausgelassene Tests.

Modernes ECMAScript

Klassen, async/await, Generatoren, Symbol, BigInt, Proxy, Temporal, TypedArray und Intl mit ext-intl. Vollständiges ES2024+.

Webplattform-APIs

URL, TextEncoder und TextDecoder, atob und btoa, structuredClone, performance und DOMException sind integriert.

fetch + Streams

Echtes HTTP aus JS über ext-curl. Vollständige Fetch-API mit AbortSignal, Blob, FormData und WHATWG Streams.

Web Platform Tests

Importierte WPT-Untertests für fetch, headers, blob, abort, streams und encoding bestehen – abgesehen von einer Allowlist mit brotli- und SharedArrayBuffer-Fällen.

PHP ↔ JS-Interop

setGlobal() stellt PHP-Closures als JS-Funktionen bereit, und call() führt JS-Funktionen aus PHP aus. Werte werden an der Grenze konvertiert; Arrays werden kopiert.

Einbettbar

Eine Engine-Klasse: eval, execFile, setGlobal, call. Integriere sie in jede PHP-App oder jedes CLI.

Begrenzter Call-Stack

Ein fester Call-Stack mit 4.096 Frames stoppt endlose Rekursion mit einem abfangbaren InternalError.

CLI

bin/phasis führt eine Datei oder ein -e-Snippet aus und gibt den AST mit --ast aus. In einem Repository-Checkout führt bin/test262 die Konformitätssuite aus.

Node.js-Referenz

Szenarien werden mit Node.js (V8) abgeglichen. WPT und die Bibliothekssuite laufen in CI bei Pushes, die die Engine betreffen; der vollständige test262-Durchlauf erfolgt bei Bedarf, zuletzt am 2026-06-09.

Echte Bibliotheken

204 npm-Pakete, darunter acorn, mustache.js, lodash und marked, werden getestet; die Ausgabe ist bytegenau wie bei Node.

Warum Phasis

Kein Node.js-Prozess

Phasis lexikalisiert, parst und führt JavaScript direkt in PHP aus – ohne exec()-Aufruf von Node und ohne FFI. Es wird als Composer-Paket installiert.

fetch unter Kontrolle des Hosts

fetch() verwendet standardmäßig ext-curl. setFetchTransport() tauscht den Transport aus, zum Beispiel gegen einen Mock für Tests, und setFetchPolicy() kann jede Anfrage vor dem Senden ablehnen oder umschreiben.

Timer mit virtueller Zeit

eval() leert die Event-Loop, bevor es zurückkehrt; die Uhr springt zum nächsten ausstehenden Timer, statt zu warten. Hosts mit langer Laufzeit können die Loop mit tickEventLoop() in Echtzeit steuern.

Parser und Formatter enthalten

Der Parser gibt einen typisierten PHP-AST zurück, der sich nach ESTree exportieren lässt. Der Formatter gibt JavaScript, JSON und CSS mit einem zu Prettier kompatiblen Layout neu aus.

Im Vergleich zu

Weitere Möglichkeiten, JavaScript aus einer PHP-Anwendung auszuführen oder zu verarbeiten.

Phasis im Vergleich zu anderen Werkzeugen
Node.js Gut geeignet fürNode.js führt JavaScript auf der V8-Engine aus und löst Pakete in node_modules-Ordnern auf, sodass sich npm-Abhängigkeiten über ihren Namen laden lassen. Unterschiede zu PhasisNode aus PHP aufzurufen, fügt eine zweite Laufzeitumgebung und eine Subprozessgrenze hinzu. Phasis läuft innerhalb von PHP, aber sein Modul-Loader kennt weder node_modules noch die Auflösung von package.json-Exports. Daher müssen npm-Pakete zuerst gebündelt werden, zum Beispiel mit esbuild.
V8Js Gut geeignet fürV8Js bindet Googles V8-Engine in PHP ein und führt JavaScript in einer Sandbox aus, die sich durch ein Zeit- und ein Speicherlimit beschränken lässt. Unterschiede zu PhasisV8Js ist eine kompilierte Erweiterung, die die libv8-Bibliothek benötigt. Phasis ist reines PHP aus Composer; laut Dokumentation erreicht es bei Code, der durch Funktionsaufrufe begrenzt ist, ungefähr die 100-fache Laufzeit von V8.
Peast Gut geeignet fürPeast parst JavaScript unter PHP 5.4 und höher in einen ESTree-AST und bietet außerdem Baumdurchläufe, Selektorabfragen und Rendering. Unterschiede zu PhasisPhasis benötigt PHP 8.2. Sein Parser gibt typisierte, schreibgeschützte Knotenobjekte mit einem ESTree-Export zurück; dasselbe Paket kann den Code auch ausführen.
Prettier Gut geeignet fürPrettier formatiert JavaScript, TypeScript, JSX, CSS, HTML, Markdown, YAML und mehr und lässt sich über npm installieren. Unterschiede zu PhasisDer Phasis-Formatter unterstützt nur JavaScript, JSON und CSS. Seine Optionen entsprechen Prettier 3.x; er läuft in PHP ohne Node.js.

Fragen und Antworten

Kurze Antworten aus der Phasis-Dokumentation.

Beginne mit der Anleitung für die ersten Schritte und lies anschließend die API-Referenz zu den Fetch-Hooks und der Event-Loop.