Перейти к содержимому

Введение

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-3 AsyncContext для передачи значений через границы асинхронных операций.
  • Поддерживает современный синтаксис — деструктуризацию, 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.
  • Дополнительные сведения — архитектура, виртуальная машина байт-кода, тесты производительности и модель тестирования с эталонными результатами.