Вступ
Phasis — це рушій JavaScript, написаний лише на PHP. Він виконує лексичний аналіз, розбирає та виконує 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 — повний пакет вебплатформи (URL, TextEncoder/Decoder, atob/btoa, structuredClone, performance, DOMException), повний пакет Fetch (fetch, Request, Response, Headers, Body, AbortController/Signal, Blob, File, FormData, EventTarget, повний набір потоків WHATWG, navigator), а також
crypto+SubtleCrypto,WebSocket,XMLHttpRequestі справжній цикл подій. Проходить 100 % імпортованих тестів вебплатформи. - Сучасний синтаксис — стрілкові функції, класи, 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 або відмовляються від цієї можливості. Обидва варіанти ускладнюють експлуатацію: друге середовище виконання, межа серіалізації, мережа каналів підпроцесів і складнощі безпечного розгортання на спільному хостингу.
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 вебплатформи, наявність яких реальні бібліотеки JS перевіряють заздалегідь:
URL,URLSearchParams,TextEncoder/TextDecoder,atob/btoa,structuredClone,performance,DOMException. Повний перелік див. у розділі Веб-API. - Постачається з
fetchі повним сімейством Fetch:Request,Response,Headers, споживачі тіла відповіді,AbortController/AbortSignal,Blob,File,FormData,EventTarget/Eventі повний набір потоків WHATWG (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, а такожAsyncContextзі стадії 3 для передавання значень через асинхронні межі. - Підтримує сучасний синтаксис: деструктуризацію, spread/rest, обчислювані властивості, опціональний ланцюжок, об’єднання з nullish, шаблонні рядки, теговані шаблони, класи (із приватними полями, статичними блоками, декораторами), top-level await.
- Перетворює значення на межі PHP↔JS. Скалярні значення й масиви копіюються під час передавання, функції PHP стають функціями JS, а результати JS повертаються як скаляри й масиви PHP. Точні правила див. у розділі Перетворення значень.
- Виконується під контролем хоста. Хост керує транспортом
fetchі хуками політик, цикл подій працює у віртуальному часі, а фіксований ліміт глибини стека викликів зупиняє нескінченну рекурсію. Ліміт ітерацій циклу є, але поки що не застосовується до циклів, які виконує байткодова ВМ; обмежень довжини рядка, виводу чи реального часу немає. Див. API: setLimit. - Перевіряється за допомогою Node.js (V8). CI запускає модульні тести й тести-оракули після кожного надсилання змін до
mainта кожного запиту на злиття, а тести вебплатформи й набори тестів популярних пакетів — коли змінюється вихідний код рушія; повну матрицю test262 запускають вручну, а її знімок додають доCOMPAT.md. Див. Сумісність.
Чим цей інструмент не є
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.
- Додаткові теми — архітектура, байткодова ВМ, бенчмарки й модель тестування з оракулом.