본문으로 건너뛰기

Phasis

JavaScript: PHP로 작성된 엔진. ES2024+ 지원, 모든 50,506 test262 테스트 통과(2025-05-05 스냅샷), URL, 인코딩, structuredClone, fetch 및 Streams 포함.

터미널
composer require phasis/phasis

최신 릴리스 v0.4.2 MIT PHP 8.2+, ext-bcmath, ext-curl, ext-mbstring

실제 사용

엔진 객체 하나로 JavaScript를 PHP 프로세스 안에서 실행하고 양방향으로 값을 전달합니다.

PHP에서 JavaScript 실행

Phasis\Engine는 자신을 호출한 PHP 프로세스 안에서 소스 문자열과 파일을 평가합니다. setGlobal()는 PHP 배열을 JavaScript 배열과 객체로 변환하고, PHP 클로저를 함수로 래핑합니다.

console.log 출력은 엔진에 버퍼링되며 getConsoleOutput()로 읽을 수 있습니다. 두 번째 탭의 포매터에는 엔진이 전혀 필요하지 않습니다.

엔진
use Phasis\Engine;

$engine = new Engine();

// Evaluate an expression
$engine->eval('1 + 2 * 3');                  // 7

// Run a file
$engine->execFile('/path/to/script.js');

// Bridge a PHP value into JS (arrays are copied)
$engine->setGlobal('config', ['debug' => true]);
$engine->eval('config.debug');               // true

// console.log is buffered, not printed
$engine->eval('console.log("hi")');
echo $engine->getConsoleOutput();            // hi

// Expose a PHP closure as a JS function
$engine->setGlobal('greet', fn(string $name) => "Hello, $name");
$engine->eval('greet("world")');             // "Hello, world"

순수 PHP

exec() 없음, FFI 없음, Node 없음. ext-curl, ext-bcmath, ext-mbstring을 포함한 PHP 8.2+가 필요하며 CI는 PHP 8.4 및 8.5에서 실행됩니다.

100% test262

ECMAScript 적합성 테스트 모음의 2025-05-05 스냅샷에서 모든 50,506 테스트를 모든 범주에서 건너뛰기 없이 통과합니다.

최신 ECMAScript

클래스, async/await, 제너레이터, Symbol, BigInt, Proxy, Temporal, TypedArray, ext-intl을 통한 Intl을 지원합니다. ES2024+ 전체 지원.

웹 플랫폼 API

URL, TextEncoder와 TextDecoder, atob와 btoa, structuredClone, performance, DOMException이 기본 제공됩니다.

fetch + 스트림

ext-curl을 통해 JS에서 실제 HTTP를 사용합니다. AbortSignal, Blob, FormData, WHATWG Streams를 포함한 완전한 Fetch API입니다.

웹 플랫폼 테스트

fetch, headers, blob, abort, streams, encoding을 위한 WPT 하위 테스트를 가져와 통과합니다. brotli 및 SharedArrayBuffer 사례의 허용 목록은 제외됩니다.

PHP ↔ JS 상호 운용

setGlobal()는 PHP 클로저를 JS 함수로 노출하고, call()는 PHP에서 JS 함수를 실행합니다. 경계에서 값을 변환하며 배열은 복사합니다.

임베드 가능

Engine 클래스 하나로 eval, execFile, setGlobal, call을 제공합니다. 모든 PHP 앱이나 CLI에 추가할 수 있습니다.

호출 스택 제한

고정된 4,096 프레임 호출 스택으로 제어할 수 없는 재귀를 막고, 잡을 수 있는 InternalError를 발생시킵니다.

CLI

bin/phasis는 파일 또는 -e 코드 조각을 실행하고 --ast로 AST를 출력합니다. 저장소를 체크아웃하면 bin/test262가 적합성 테스트 모음을 실행합니다.

Node.js 오라클

시나리오는 Node.js(V8)과 대조해 확인합니다. 엔진을 수정하는 푸시가 있으면 CI에서 WPT와 라이브러리 테스트 모음을 실행합니다. 전체 test262 검증은 요청 시 실행하며, 마지막 실행일은 2026-06-09입니다.

실제 라이브러리

acorn, mustache.js, lodash, marked 등을 포함한 204 npm 패키지를 테스트하며, 출력은 Node와 바이트 단위로 동일합니다.

Phasis를 사용하는 이유

Node.js 프로세스 불필요

Phasis는 PHP 자체에서 JavaScript을 어휘 분석하고, 파싱하고, 실행하며, Node 호출이나 FFI 호출이 필요하지 않습니다. Composer 패키지로 설치됩니다.exec()

호스트에서 제어하는 fetch

fetch()는 기본적으로 ext-curl을 사용합니다. setFetchTransport()로 전송 방식을 바꿀 수 있어 테스트에서 모의 객체를 사용할 수 있으며, setFetchPolicy()를 사용하면 요청을 보내기 전에 각각 거부하거나 다시 작성할 수 있습니다.

가상 시간 기반 타이머

eval()는 반환하기 전에 이벤트 루프를 모두 처리하며, 대기하는 대신 다음 타이머가 예정된 시각으로 시계를 이동합니다. 오래 실행되는 호스트는 tickEventLoop()로 루프를 실시간 구동할 수 있습니다.

파서와 포매터 포함

파서는 형식화된 PHP AST를 반환하고 ESTree로 내보냅니다. 포매터는 prettier와 호환되는 레이아웃으로 JavaScript, JSON, CSS를 다시 출력합니다.

비교 대상

PHP 애플리케이션에서 JavaScript를 실행하거나 처리하는 다른 방법입니다.

Phasis와 다른 도구 비교
Node.js 잘하는 점Node.js는 V8 엔진에서 JavaScript를 실행하고 node_modules 폴더에서 패키지를 찾아 npm 종속성을 이름으로 불러옵니다. Phasis와의 차이점PHP에서 Node를 호출하면 두 번째 런타임과 하위 프로세스 경계가 추가됩니다. Phasis는 PHP 안에서 실행되지만 모듈 로더가 node_modules 또는 package.json 내보내기 확인을 지원하지 않습니다. 따라서 esbuild 등을 사용해 npm 패키지를 먼저 번들링해야 합니다.
V8Js 잘하는 점V8Js는 PHP에서 Google의 V8 엔진을 임베드하고 JavaScript를 샌드박스에서 실행합니다. 시간 및 메모리 제한을 설정할 수 있습니다. Phasis와의 차이점V8Js는 libv8 라이브러리가 필요한 컴파일된 확장입니다. Phasis는 Composer로 작성된 순수 PHP이며, 문서에 따르면 디스패치가 병목인 코드에서 V8보다 런타임이 대략 100배입니다.
Peast 잘하는 점Peast는 PHP 5.4 이상에서 JavaScript를 ESTree AST로 구문 분석하고 트리 순회, 선택자 쿼리, 렌더링을 추가합니다. Phasis와의 차이점Phasis에는 PHP 8.2가 필요합니다. 파서는 형식화되고 변경할 수 없는 노드 객체를 반환하며 ESTree로 내보낼 수 있습니다. 같은 패키지로 코드도 실행할 수 있습니다.
Prettier 잘하는 점Prettier는 JavaScript, TypeScript, JSX, CSS, HTML, Markdown, YAML 등을 포맷하며 npm에서 설치할 수 있습니다. Phasis와의 차이점Phasis 포매터는 JavaScript, JSON, CSS만 지원합니다. 옵션은 prettier 3.x와 유사하며 PHP에서 실행되고 Node.js는 없습니다.

질문과 답변

Phasis 문서의 간단한 답변.

시작하기 안내서를 읽은 다음, fetch 훅과 이벤트 루프에 대한 API 참조 문서를 읽으세요.