Введение
Phasis — это чистый PHP-движок JavaScript. Он выполняет лексический анализ, разбирает и исполняет ECMAScript в процессе хоста PHP — без exec('node …'), без FFI и без пользовательского бинарного расширения. Для работы нужны три стандартных расширения PHP: ext-mbstring, ext-bcmath и ext-curl (транспорт fetch() по умолчанию). ext-intl и ext-openssl необязательны. Сборки без bcmath описаны в Начале работы.
- Встраиваемый — добавьте среду выполнения JS в любое приложение PHP, фреймворк или инструмент CLI через класс
Phasis\Engine. - Соответствует спецификации — проходит официальный набор тестов test262 на 100 %, во всех категориях, без пропусков.
- Веб-API — полный Web Platform Pack (URL, TextEncoder/Decoder, atob/btoa, structuredClone, performance, DOMException), полный Fetch Pack (fetch, Request, Response, Headers, Body, AbortController/Signal, Blob, File, FormData, EventTarget, полный WHATWG Streams, navigator), а также
crypto+SubtleCrypto,WebSocket,XMLHttpRequestи полноценный цикл событий. Проходят 100 % импортированных Web Platform Tests. - Современные возможности — стрелочные функции, классы, async/await, Promises, генераторы, Symbol, BigInt, Proxy, Reflect, Temporal, Intl, TypedArrays, полная поддержка модулей.
- Взаимодействие PHP↔JS — передавайте скаляры и массивы PHP в JS (массивы копируются), привязывайте замыкания PHP как функции JS и вызывайте функции JS из PHP. Объектами PHP пока нельзя делиться с JS; см. Общие объекты.
Зачем нужен Phasis
PHP-приложениям, которым нужно выполнять пользовательский JavaScript, — например, шаблонизаторам, прослойкам для SSR интерфейса, правилам проверки данных, изолированным средам для контента и автономным средствам запуска тестов, — обычно приходится запускать Node.js во внешнем процессе или отказываться от этой функции. Оба варианта усложняют эксплуатацию: требуется вторая среда выполнения, граница сериализации, сеть каналов между подпроцессами и сложная для развертывания архитектура на shared-хостинге.
Phasis решает эту задачу. Ваш код PHP может выполнять лексический анализ, разбирать и исполнять JavaScript, используя только PHP 8.2+ с mbstring, bcmath и curl. Движок поставляется как пакет Composer и предоставляет небольшой интерфейс API.
Возможности
- Реализует всю стандартную библиотеку ECMAScript:
Array,String,Object,Math,JSON,Date,RegExp,Map,Set,Promise,Proxy,Reflect,Symbol,BigInt,TypedArray,Temporal,Intl, генераторы, асинхронные итераторы, модули. - Предоставляет API Web Platform, наличие которых реальные библиотеки JS проверяют заранее:
URL,URLSearchParams,TextEncoder/TextDecoder,atob/btoa,structuredClone,performance,DOMException. Полный список возможностей см. в разделе Веб-API. - Предоставляет
fetchсо всем семейством Fetch:Request,Response,Headers, средства чтения тела,AbortController/AbortSignal,Blob,File,FormData,EventTarget/Eventи полный WHATWG Streams (ReadableStream,WritableStream,TransformStream, BYOB, стратегии очередей). Полноценный HTTP работает сразу благодаря PHP и егоext-curl. - Предоставляет
cryptoи полныйSubtleCrypto(семейство SHA, HMAC, AES-GCM/CBC/CTR, RSA-OAEP/PSS/PKCS1, ECDSA, ECDH, HKDF, PBKDF2),WebSocket(RFC 6455 и сменный транспорт) иXMLHttpRequest(работает поверх того же транспорта Fetch). - Предоставляет полноценный цикл событий:
setTimeout,setInterval,clearTimeout,clearInterval,queueMicrotask, а также Stage-3AsyncContextдля передачи значений через границы асинхронных операций. - Поддерживает современный синтаксис — деструктуризацию, spread/rest, вычисляемые свойства, опциональную цепочку вызовов, оператор объединения с null, шаблонные строки, шаблоны с тегами, классы (с приватными полями, статическими блоками, декораторами), await верхнего уровня.
- Преобразует значения на границе PHP↔JS. Скалярные значения и массивы копируются при передаче внутрь, вызываемые объекты PHP становятся функциями JS, а результаты JS возвращаются как скалярные значения и массивы PHP. Точные правила см. в разделе Преобразование значений.
- Работает под управлением хоста. Хост управляет транспортом
fetchи хуками политик; цикл событий использует виртуальное время, а фиксированный предел глубины стека вызовов останавливает бесконечную рекурсию. Ограничение числа итераций цикла предусмотрено, но пока не применяется к циклам, выполняемым виртуальной машиной байт-кода; также нет ограничений на длину строк, вывод или реальное время. См. API: setLimit. - Проверяется с помощью Node.js (V8). CI запускает наборы модульных тестов и тестов с эталонными результатами при каждом отправлении изменений в
mainи каждом pull request, а Web Platform Tests и тесты популярных пакетов — при изменении исходного кода движка. Полная матрица test262 запускается вручную, а ее снимок фиксируется вCOMPAT.md. См. Совместимость.
Чем merql не является
Phasis — не JIT-компилятор. Это интерпретатор с обходом дерева и виртуальной машиной байт-кода, которая используется при подходящих условиях. В задачах, ограниченных диспетчеризацией, ожидайте скорость примерно в 100× ниже, чем у V8. Компромисс — отсутствие зависимостей, чистый PHP и выполнение под управлением хоста: это идеально для встраивания JavaScript в приложения PHP, где корректность и изоляция важнее максимальной пропускной способности.
С чего начать
- Начало работы — установите и запустите первый скрипт.
- CLI —
bin/phasisдля запуска файлов, вычисления исходного кода и вывода AST. - API — встроить
Phasis\Engineв приложение PHP. - Взаимодействие — передавайте значения и вызываемые объекты PHP в JavaScript.
- Совместимость — покрытие test262 и поддерживаемые возможности.
- Парсер — разбирайте JavaScript в типизированное AST или ESTree без выполнения.
- Форматтер — форматируйте JavaScript, JSON и CSS в стиле, совместимом с Prettier.
- Дополнительные сведения — архитектура, виртуальная машина байт-кода, тесты производительности и модель тестирования с эталонными результатами.