
# 快速入门

## 安装

```bash
composer require phasis/phasis
```

Phasis 需要 PHP 8.2 或更高版本，以及三个扩展；它们都是 `composer.json` 所必需的：

- `mbstring` — 字符串处理。
- `bcmath` — BigInt 运算和整数精度数值处理。
- `curl` — `fetch()` 背后的默认传输机制。

`mbstring` 和 `curl` 在大多数构建中均已启用。`bcmath` 通常未启用：官方 `php` Docker 镜像（`php:8.x-cli`、`php:8.x-fpm`）未包含它，有些发行版则将其单独打包（`php-bcmath`）。缺少它时，Composer 会拒绝安装 Phasis。如果 Dockerfile 基于官方镜像，请添加：

```dockerfile
RUN docker-php-ext-install bcmath
```

运行 `php -m`，查看你的构建启用了哪些扩展。

`ext-intl` 是可选的。Phasis 即使没有它也能运行，但整个 `Intl.*` 系列（`Collator`、`NumberFormat`、`DateTimeFormat`、`PluralRules`、`Locale`、`DisplayNames`、`ListFormat`、`RelativeTimeFormat`、`Segmenter`、`DurationFormat`）以及非 ISO 的 Temporal 日历（`hebrew`、`islamic`、`japanese`、`persian` 等）都需要它。只要宿主应用提供涉及区域设置格式化的 JS，就应安装它。`ext-openssl` 也是可选的：`crypto.subtle` 的 AES-CBC、AES-CTR 和 AES-GCM 加密需要它，而摘要和 HMAC 无需它也能运行。

无需 `exec`，无需 FFI，无需 Node.js，也无需自定义原生扩展。

## 从 CLI 运行脚本

```bash
./vendor/bin/phasis -e 'console.log(1 + 2 * 3)'
# 7

./vendor/bin/phasis -e 'console.log([1, 2, 3].map(x => x * x).join(","))'
# 1,4,9

./vendor/bin/phasis path/to/script.js
```

CLI 会输出脚本通过 `console.log` 写入的内容；它不会输出最后一个表达式的值。

完整命令集请参阅 [CLI 命令参考](https://phasis.inline0.dev/zh/docs/cli)。

## 在 PHP 中嵌入

```php
<?php

require __DIR__ . '/vendor/autoload.php';

use Phasis\Engine;

$engine = new Engine();

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

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

// Bridge a PHP value into the JS global scope
$engine->setGlobal('config', ['debug' => true, 'version' => '1.0']);
$engine->eval('console.log(config.version)');

// console output is buffered on the engine, not printed
echo $engine->getConsoleOutput();
// 1.0
```

`Engine` 实例会在多次调用之间保留其全局状态，因此后续调用 `eval()` 时可以使用之前定义的内容。

`console.log` 及其同类方法会将内容追加到引擎的缓冲区，而不是写入 stdout。可通过 `getConsoleOutput()`（一个字符串，各行以 `\n` 连接）或 `getConsoleLines()`（行列表）读取，并通过 `clearConsole()` 清空。

冷启动开销很低：仅预先安装规范加载所需的核心部分（`Object`、`Function`、`Array`、`Promise`、`Symbol`、`BigInt`、`RegExp` 和错误类型）。`Map`、`TypedArray`、`Temporal`、`Intl`、`URL`、`fetch`、完整的 Web Platform / Fetch Packs 以及其他所有内容，都会在首次读取时透明地实例化。构造时传入 `new Engine(eager: true)` 可安装所有内置项——适用于在读取描述符之前检查它们的一致性工具；常规嵌入通常无需此选项。

## 从 PHP 调用 JS 函数

```php
$engine->eval('function add(a, b) { return a + b; }');
echo $engine->call('add', 2, 3);
// 5
```

`call()` 会按名称在全局对象上查找函数，并使用提供的 PHP 参数调用它（参数会自动转换为 JS 值）。

## 将可调用的 PHP 暴露为 JS 函数

```php
$engine->setGlobal('fetchData', function (string $url): array {
    return json_decode(file_get_contents($url), true);
});

$engine->eval('const users = fetchData("https://api.example.com/users")');
```

PHP 闭包会被包装为 JS 函数。调用时，参数会从 JS 转换为 PHP，返回值则会从 PHP 转换回 JS。

## PHP 对象

PHP 对象目前还不能与 JavaScript 共享。将普通 PHP 对象传给 `setGlobal()` 会绑定 `undefined`（相关问题见 [issue #18](https://github.com/inline0/phasis/issues/18)）。请将数据作为数组传递；数组会被复制到 JS 中，并将行为作为闭包暴露：

```php
class Counter {
    public int $value = 0;
    public function increment(): void { $this->value++; }
}

$counter = new Counter();
$engine->setGlobal('increment', fn () => $counter->increment());

$engine->eval('increment(); increment();');

echo $counter->value;
// 2
```

详情及其他变通方法请参阅 [共享对象](https://phasis.inline0.dev/zh/docs/interop/shared-objects)。

## 资源限制

```php
$engine = new Engine();
$engine->setLimit('maxLoopIterations', 100_000);
```

`maxLoopIterations`（默认值为 100,000）是唯一可在运行时调整的限制，目前仅适用于树遍历解释器运行的代码。字节码 VM 运行的循环（函数体和大多数顶层代码）不计入限制，因此仅靠这一限制无法阻止 `while (true) {}`（[issue #19](https://github.com/inline0/phasis/issues/19)）。达到限制时，可在 JS 中捕获错误；若未捕获，错误会以 `Phasis\Exceptions\InternalError` 的形式传递到 PHP，它是 `Phasis\Exceptions\RuntimeError` 的子类。

引擎还设有固定的 4,096 帧调用栈上限（转译闭包另有 8,192 帧保护）；超过上限会抛出“Maximum call stack size exceeded”，同样属于 `InternalError`。引擎没有墙钟时间限制，因此请在 PHP 自身的 `max_execution_time` 中或单独进程里运行不可信代码。参阅 [API：setLimit](https://phasis.inline0.dev/zh/docs/api#setlimit)。

## 后续步骤

- [API 参考](https://phasis.inline0.dev/zh/docs/api) — 完整的 `Phasis\Engine` 接口。
- [互操作](https://phasis.inline0.dev/zh/docs/interop) — 值转换规则、宿主函数和 PHP 对象。
- [兼容性](https://phasis.inline0.dev/zh/docs/compatibility) — 已实现的功能和 test262 覆盖率。
- [解析器](https://phasis.inline0.dev/zh/docs/parser)和[格式化程序](https://phasis.inline0.dev/zh/docs/formatter) — 解析和格式化 JavaScript，而不执行它。
- [高级主题](https://phasis.inline0.dev/zh/docs/advanced) — 架构、字节码 VM、基准测试和预言机测试。
