Introdução
Phasis é um motor JavaScript escrito inteiramente em PHP. Ele analisa léxica e sintaticamente e executa ECMAScript no processo PHP do host — sem exec('node …'), sem FFI e sem uma extensão binária personalizada. Requer três extensões padrão de PHP: ext-mbstring, ext-bcmath e ext-curl (o transporte fetch() padrão). ext-intl e ext-openssl são opcionais. Consulte Primeiros passos para compilações que não incluem bcmath.
- Incorporável — adicione um runtime JS a qualquer app PHP, framework ou ferramenta CLI pela classe
Phasis\Engine. - Em conformidade com as especificações — passa na suíte oficial test262 com 100 %, em todas as categorias, sem ignorar testes.
- APIs da Web — pacote completo Web Platform Pack (URL, TextEncoder/Decoder, atob/btoa, structuredClone, performance, DOMException), pacote completo Fetch Pack (fetch, Request, Response, Headers, Body, AbortController/Signal, Blob, File, FormData, EventTarget, fluxos WHATWG completos, navigator), além de
crypto+SubtleCrypto,WebSocket,XMLHttpRequeste um loop de eventos real. 100 % dos Web Platform Tests importados passam. - Recursos modernos — funções de seta, classes, async/await, Promises, geradores, Symbol, BigInt, Proxy, Reflect, Temporal, Intl, TypedArrays, suporte completo a módulos.
- Interop PHP↔JS — passe escalares e arrays PHP para JS (os arrays são copiados), vincule closures PHP como funções JS e chame funções JS de PHP. Objetos PHP ainda não podem ser compartilhados com JS; consulte Objetos compartilhados.
Por que Phasis existe
Aplicativos PHP que precisam executar JavaScript fornecido pelo usuário — mecanismos de templates, shims de SSR de frontend, regras de validação de dados, sandboxes de conteúdo, executores de testes headless — geralmente recorrem a Node.js ou deixam esse recurso de lado. Qualquer uma das opções aumenta a complexidade operacional: um segundo runtime, uma fronteira de serialização, uma rede de pipes entre subprocessos e dificuldades de implantação em hospedagem compartilhada.
Phasis preenche essa lacuna. Seu código PHP pode analisar léxica e sintaticamente e executar JavaScript usando apenas PHP 8.2+ com mbstring, bcmath e curl. O mecanismo é distribuído como um pacote Composer e oferece uma pequena interface API única.
O que ele faz
- Implementa a biblioteca padrão completa do ECMAScript:
Array,String,Object,Math,JSON,Date,RegExp,Map,Set,Promise,Proxy,Reflect,Symbol,BigInt,TypedArray,Temporal,Intl, geradores, iteradores assíncronos, módulos. - Inclui as APIs da Web Platform que bibliotecas JS do mundo real verificam previamente:
URL,URLSearchParams,TextEncoder/TextDecoder,atob/btoa,structuredClone,performance,DOMException. Consulte APIs da Web para ver a interface completa. - Inclui
fetchcom toda a família Fetch —Request,Response,Headers, consumidores do corpo,AbortController/AbortSignal,Blob,File,FormData,EventTarget/Evente WHATWG Streams completo (ReadableStream,WritableStream,TransformStream, BYOB, estratégias de enfileiramento). O HTTP real funciona imediatamente por meio de PHP'sext-curl. - Inclui
crypto+SubtleCryptocompleto (família SHA, HMAC, AES-GCM/CBC/CTR, RSA-OAEP/PSS/PKCS1, ECDSA, ECDH, HKDF, PBKDF2),WebSocket(RFC 6455 + transporte substituível) eXMLHttpRequest(sobre o mesmo transporte fetch). - Inclui um loop de eventos real:
setTimeout,setInterval,clearTimeout,clearInterval,queueMicrotask, além deAsyncContextStage-3 para propagação de valores entre limites assíncronos. - Oferece suporte à sintaxe moderna — desestruturação, spread/rest, propriedades computadas, encadeamento opcional, coalescência de nulos, literais de template, templates marcados, classes (com campos privados, blocos estáticos e decorators), await no nível superior.
- Converte valores entre as fronteiras PHP↔JS. Escalares e arrays são copiados para dentro, funções chamáveis PHP tornam-se funções JS e resultados JS retornam como escalares e arrays PHP. Consulte Conversão de valores para ver as regras exatas.
- Executa sob controle do host. O host controla o transporte
fetche os hooks de política, o loop de eventos funciona com tempo virtual e um limite fixo de chamadas na pilha impede recursão descontrolada. Há um limite de iterações do loop, mas ele ainda não é aplicado aos loops executados pela VM de bytecode; também não há limites de comprimento de strings, saída ou tempo de relógio. Consulte API: definirLimite. - É verificado com Node.js (V8). A CI executa as suítes unitária e oracle a cada push para
maine a cada pull request, além das suítes Web Platform Tests e de pacotes populares quando o código-fonte do mecanismo muda; a matriz completa test262 é executada manualmente e seu snapshot é enviado paraCOMPAT.md. Consulte Compatibilidade.
O que não é
Phasis não é um compilador JIT. É um interpretador que percorre árvores, com uma VM de bytecode oportunista. Espere cerca de 100× o tempo de execução de V8 em cargas limitadas pelo despacho. A contrapartida é não ter dependências, ser PHP puro e oferecer execução controlada pelo host — ideal para incorporar JavaScript em aplicativos PHP, nos quais a correção e o isolamento importam mais do que a vazão bruta.
Por onde começar
- Primeiros passos — instale e execute seu primeiro script.
- CLI —
bin/phasispara executar arquivos, avaliar código-fonte e exibir a AST. - API — incorpore
Phasis\Engineno seu aplicativo PHP. - Interoperação — passe valores e funções chamáveis de PHP para JavaScript.
- Compatibilidade — cobertura test262 e recursos compatíveis.
- Analisador — analise JavaScript em uma AST tipada ou ESTree sem executá-lo.
- Formatador — formate JavaScript, JSON e CSS com um layout compatível com prettier.
- Avançado — arquitetura, VM de bytecode, benchmarks e o modelo de testes oracle.