
# Kezdő lépések

## Telepítés

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

A Phasis használatához PHP 8.2 vagy újabb verziója szükséges, három bővítménnyel, amelyeket mind a `composer.json` igényel:

- `mbstring` — karakterláncok kezelése.
- `bcmath` — BigInt-aritmetika és egész számok pontos kezelése.
- `curl` — a `fetch()` mögötti alapértelmezett transzport.

A `mbstring` és a `curl` a legtöbb buildben engedélyezve van. A `bcmath` viszont gyakran nincs: a hivatalos `php` Docker-képek (`php:8.x-cli`, `php:8.x-fpm`) kihagyják, egyes disztribúciók pedig külön csomagolják (`php-bcmath`). Nélküle a Composer nem hajlandó telepíteni a Phasis csomagot. A hivatalos képre épülő Dockerfile-ban adja hozzá ezt:

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

Futtassa a `php -m` parancsot, hogy megtudja, mely bővítmények érhetők el a buildben.

A `ext-intl` opcionális. A Phasis nélküle is működik, de a teljes `Intl.*` családnak (`Collator`, `NumberFormat`, `DateTimeFormat`, `PluralRules`, `Locale`, `DisplayNames`, `ListFormat`, `RelativeTimeFormat`, `Segmenter`, `DurationFormat`) és a nem ISO típusú Temporal-naptáraknak (`hebrew`, `islamic`, `japanese`, `persian` stb.) szüksége van rá. Telepítse, ha a gazdaalkalmazás olyan JS lehetőséget biztosít, amely lokalizációt figyelembe vevő formázást végez. A `ext-openssl` szintén opcionális: a `crypto.subtle` AES-CBC, AES-CTR és AES-GCM titkosításhoz szükséges, míg a digest és a HMAC nélküle is működik.

Nincs `exec`, FFI, Node.js vagy egyéni natív bővítmény.

## Szkript futtatása a CLI parancssorból

```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
```

A CLI kiírja, amit a szkript a `console.log` segítségével kiír; az utolsó kifejezés értékét nem jeleníti meg.

A teljes parancskészletet lásd a [CLI-referenciában](https://phasis.inline0.dev/hu/docs/cli).

## Beágyazás a PHP alkalmazásba

```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
```

A `Engine` példánya megőrzi globális állapotát a hívások között, így a későbbi `eval()` hívások látják mindazt, amit korábban definiált.

A `console.log` és társai a motor egyik pufferébe írnak a stdout helyett. Olvassa ki a `getConsoleOutput()` segítségével (egy karakterlánc, a sorokat `\n` kapcsolja össze) vagy a `getConsoleLines()` segítségével (sorok listája), a puffert pedig ürítse ki ezzel: `clearConsole()`.

A hidegindítás gyors: kezdetben csak a specifikáció betöltéséhez szükséges mag (`Object`, `Function`, `Array`, `Promise`, `Symbol`, `BigInt`, `RegExp` és a hibatípusok) települ. A `Map`, `TypedArray`, `Temporal`, `Intl`, `URL`, `fetch`, a teljes Web Platform / Fetch Pack és minden más csak az első olvasáskor, átláthatóan töltődik be. Adja meg a `new Engine(eager: true)` beállítást, hogy konstrukciókor minden beépített elem települjön — ez olyan megfelelőségi eszközöknél hasznos, amelyek olvasás előtt vizsgálják meg a leírókat; normál beágyazáshoz ritkán szükséges.

## PHP-ből JS-függvények hívása

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

A `call()` név alapján megkeresi a függvényt a globális objektumon, és a megadott PHP argumentumokkal hívja meg (amelyek automatikusan JS értékekké alakulnak).

## PHP-beli hívható elem közzététele JS-függvényként

```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")');
```

A PHP-beli lezárások JS-függvényekként kapnak burkolót. A híváskor argumentumaik JS-ről PHP-ra, visszatérési értékeik pedig PHP-ről JS-ra alakulnak.

## PHP-objektumok

A PHP objektumai egyelőre nem oszthatók meg a JavaScript használatával. A sima PHP objektummal végzett `setGlobal()`-kötés a `undefined` értéket rendeli hozzá (a [#18. számú issue-ban](https://github.com/inline0/phasis/issues/18) követhető). Az adatokat tömbként adja át, amelyek bemásolódnak a JS-be, a viselkedést pedig tegye elérhetővé lezárásokként:

```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
```

A részletekért és további kerülőmegoldásokért lásd a [Megosztott objektumok](https://phasis.inline0.dev/hu/docs/interop/shared-objects) oldalt.

## Erőforráskorlátok

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

A `maxLoopIterations` (alapértelmezett értéke 100,000) az egyetlen futás közben módosítható korlát, és jelenleg csak a faalapú értelmező által futtatott kódra vonatkozik. A bájtkód-VM által futtatott ciklusokat (függvénytörzsek és a legtöbb legfelső szintű kód) nem számolja, ezért önmagában a korlát nem állítja meg a `while (true) {}` működését ([19.](https://github.com/inline0/phasis/issues/19) hibajegy). A korlát elérésekor a hiba elkapható a JS segítségével; ha nem kapják el, PHP formájában jut el a `Phasis\Exceptions\InternalError`-hoz, amely a `Phasis\Exceptions\RuntimeError` egyik alosztálya.

A motorban rögzített 4,096-keretes hívásveremkorlát van (transzpált lezárásoknál pedig 8,192-keretes védelemmel); túllépésekor „Maximum call stack size exceeded” hiba keletkezik, ismét `InternalError` formájában. Nincs valós időn alapuló korlát, ezért nem megbízható kódot a PHP saját `max_execution_time` korlátja alatt vagy külön folyamatban futtasson. Lásd: [API: setLimit](https://phasis.inline0.dev/hu/docs/api#setlimit).

## Következő lépések

- [API-referencia](https://phasis.inline0.dev/hu/docs/api) — a teljes `Phasis\Engine`-felület.
- [Együttműködés](https://phasis.inline0.dev/hu/docs/interop) — értékkonverziós szabályok, gazdagépi függvények, PHP-objektumok.
- [Kompatibilitás](https://phasis.inline0.dev/hu/docs/compatibility) — mi van megvalósítva, test262-lefedettség.
- [Parser](https://phasis.inline0.dev/hu/docs/parser) és [Formázó](https://phasis.inline0.dev/hu/docs/formatter) — JavaScript feldolgozása és formázása futtatás nélkül.
- [Haladó témák](https://phasis.inline0.dev/hu/docs/advanced) — architektúra, bájtkód-VM, benchmarkok, orákulumtesztek.
