Introduzione
Phasis è un motore JavaScript scritto interamente in PHP. Analizza lessicalmente e sintatticamente ed esegue ECMAScript nel processo host PHP, senza exec('node …'), senza FFI e senza un'estensione binaria personalizzata. Richiede tre estensioni standard di PHP: ext-mbstring, ext-bcmath e ext-curl (il trasporto predefinito fetch()). ext-intl e ext-openssl sono facoltativi. Consultate Per iniziare per le build che escludono bcmath.
- Integrabile — inserite un runtime JS in qualsiasi app, framework o strumento CLI PHP tramite la classe
Phasis\Engine. - Conforme alle specifiche — supera la suite ufficiale test262 al 100%, in ogni categoria, senza test saltati.
- API web — Web Platform Pack completo (URL, TextEncoder/Decoder, atob/btoa, structuredClone, performance, DOMException), Fetch Pack completo (fetch, Request, Response, Headers, Body, AbortController/Signal, Blob, File, FormData, EventTarget, WHATWG Streams completi, navigator), oltre a
crypto+SubtleCrypto,WebSocket,XMLHttpRequeste un vero event loop. Supera il 100% dei Web Platform Tests importati. - Funzionalità moderne — funzioni freccia, classi, async/await, Promises, generatori, Symbol, BigInt, Proxy, Reflect, Temporal, Intl, TypedArrays, supporto completo ai moduli.
- Interop PHP↔JS — passate scalari e array PHP a JS (gli array vengono copiati), associate closure PHP come funzioni JS e chiamate funzioni JS da PHP. Gli oggetti PHP non possono ancora essere condivisi con JS; consultate Oggetti condivisi.
Perché esiste Phasis
Le applicazioni PHP che devono eseguire codice JavaScript fornito dagli utenti — motori di template, shim SSR per frontend, regole di convalida dei dati, sandbox per i contenuti, runner di test headless — in genere avviano Node.js come processo esterno oppure rinunciano alla funzionalità. Entrambe le soluzioni aggiungono complessità operativa: un secondo runtime, un confine di serializzazione, una rete di pipe tra sottoprocessi e difficoltà di deployment negli ambienti di hosting condiviso.
Phasis colma questa lacuna. Il vostro codice PHP può eseguire il lessing, l'analisi sintattica e l'esecuzione di JavaScript usando solo PHP 8.2+ con mbstring, bcmath e curl. Il motore viene distribuito come pacchetto Composer ed espone una superficie API piccola e unificata.
Cosa fa
- Implementa la libreria standard ECMAScript completa:
Array,String,Object,Math,JSON,Date,RegExp,Map,Set,Promise,Proxy,Reflect,Symbol,BigInt,TypedArray,Temporal,Intl, generatori, iteratori asincroni, moduli. - Include le API della Web Platform che le librerie JS per uso reale verificano in anticipo:
URL,URLSearchParams,TextEncoder/TextDecoder,atob/btoa,structuredClone,performance,DOMException. Consultate API web per l'elenco completo. - Include
fetchcon tutta la famiglia Fetch:Request,Response,Headers, metodi per leggere il corpo,AbortController/AbortSignal,Blob,File,FormData,EventTarget/Evente WHATWG Streams completi (ReadableStream,WritableStream,TransformStream, BYOB, strategie di accodamento). Un vero HTTP funziona subito tramite PHPext-curl. - Include
crypto+SubtleCryptocompleto (famiglia SHA, HMAC, AES-GCM/CBC/CTR, RSA-OAEP/PSS/PKCS1, ECDSA, ECDH, HKDF, PBKDF2),WebSocket(RFC 6455 + trasporto sostituibile) eXMLHttpRequest(basato sullo stesso trasporto fetch). - Include un vero event loop:
setTimeout,setInterval,clearTimeout,clearInterval,queueMicrotaskeAsyncContextStage-3 per propagare i valori attraverso i confini asincroni. - Supporta la sintassi moderna: destrutturazione, spread/rest, proprietà calcolate, concatenamento opzionale, coalescenza nullish, template literal, template taggati, classi (con campi privati, blocchi statici e decorator), await al livello superiore.
- Converte i valori attraverso il confine PHP↔JS. Gli scalari e gli array vengono copiati, i callable PHP diventano funzioni JS e i risultati JS vengono restituiti come scalari e array PHP. Consultate Conversione dei valori per le regole precise.
- L'esecuzione è controllata dall'host. L'host gestisce il trasporto
fetche gli hook delle policy, l'event loop funziona in tempo virtuale e un limite fisso alla profondità dello stack di chiamate arresta la ricorsione incontrollata. Esiste un limite alle iterazioni dei loop, ma non viene ancora applicato ai loop eseguiti dalla VM bytecode; inoltre non ci sono limiti alla lunghezza delle stringhe, all'output o al tempo reale. Consultate API: setLimit. - La compatibilità viene verificata con Node.js (V8). La CI esegue le suite di unit test e oracle a ogni push su
maine a ogni pull request; esegue inoltre i Web Platform Tests e le suite dei pacchetti più diffusi quando cambia il codice sorgente del motore. L'intera matrice test262 viene eseguita manualmente e il relativo snapshot viene salvato inCOMPAT.md. Consultate Compatibilità.
Cosa non è
Phasis non è un compilatore JIT. È un interprete che attraversa l'albero sintattico, affiancato da una VM bytecode usata quando possibile. Nei carichi di lavoro limitati dalla dispatch, aspettatevi tempi di esecuzione circa 100× superiori a quelli di V8. Il compromesso è l'assenza di dipendenze, PHP puro ed esecuzione controllata dall'host: una soluzione ideale per integrare JavaScript nelle app PHP, dove correttezza e isolamento contano più della velocità massima.
Da dove iniziare
- Per iniziare — installate il motore ed eseguite il vostro primo script.
- CLI —
bin/phasisper eseguire file, valutare il codice sorgente e stampare l'AST. - API — integrate
Phasis\Enginenella vostra app PHP. - Interop — passate valori e callable PHP a JavaScript.
- Compatibilità — copertura test262 e funzionalità supportate.
- Parser — analizzate JavaScript in un AST tipizzato o in ESTree senza eseguirlo.
- Formatter — formattate JavaScript, JSON e CSS con un layout compatibile con prettier.
- Avanzate — architettura, VM bytecode, benchmark e modello di test oracle.