
# Darbo pradžia

## Diegimas

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

Phasis reikia PHP 8.2 arba naujesnės versijos su trimis plėtiniais, kurių visų reikia `composer.json`:

- `mbstring` — eilučių apdorojimas.
- `bcmath` — BigInt aritmetika ir tikslaus sveikųjų skaičių apdorojimas.
- `curl` — numatytoji transporto priemonė, naudojama `fetch()`.

`mbstring` ir `curl` daugumoje darinių įjungti. `bcmath` dažnai neįjungtas: oficialiuose `php` Docker atvaizduose (`php:8.x-cli`, `php:8.x-fpm`) jo nėra, o kai kuriuose platinamuosiuose paketuose jis pateikiamas atskirai (`php-bcmath`). Be jo Composer atsisako įdiegti Phasis. Jei Dockerfile pagrįstas oficialiu atvaizdu, pridėkite:

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

Paleiskite `php -m`, kad pamatytumėte, kurie plėtiniai įtraukti į jūsų darinį.

`ext-intl` yra pasirenkamas. Phasis veikia ir be jo, tačiau visai `Intl.*` šeimai (`Collator`, `NumberFormat`, `DateTimeFormat`, `PluralRules`, `Locale`, `DisplayNames`, `ListFormat`, `RelativeTimeFormat`, `Segmenter`, `DurationFormat`) ir ne ISO Temporal kalendoriams (`hebrew`, `islamic`, `japanese`, `persian` ir kt.) jo reikia. Įdiekite jį, kai tik pagrindinė programa pateikia JS, kuri naudoja nuo lokalės priklausantį formatavimą. `ext-openssl` taip pat pasirenkamas: `crypto.subtle` AES-CBC, AES-CTR ir AES-GCM šifravimui jo reikia, o santraukos ir HMAC veikia be jo.

Nereikia `exec`, FFI, Node.js ar pasirinktinio gimtojo plėtinio.

## Paleiskite scenarijų iš 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 išveda tai, ką scenarijus įrašo naudodamas `console.log`; paskutinės išraiškos reikšmės jis neišveda.

Visą komandų sąrašą rasite [CLI žinyne](https://phasis.inline0.dev/lt/docs/cli).

## Įterpimas į 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` egzempliorius išsaugo savo globalią būseną tarp iškvietimų, todėl vėlesni `eval()` iškvietimai gali pasiekti viską, ką apibrėžėte anksčiau.

`console.log` ir giminingi metodai prideda duomenis į variklio buferį, o ne rašo į stdout. Nuskaitykite naudodami `getConsoleOutput()` (vieną eilutę, kurioje eilutės sujungtos su `\n`) arba `getConsoleLines()` (eilučių sąrašą), o buferį išvalykite naudodami `clearConsole()`.

Pirmasis paleidimas greitas: iš anksto įdiegiama tik specifikacijai būtina branduolio dalis (`Object`, `Function`, `Array`, `Promise`, `Symbol`, `BigInt`, `RegExp`, klaidų tipai). `Map`, `TypedArray`, `Temporal`, `Intl`, `URL`, `fetch`, visi Web Platform / Fetch paketai ir visa kita skaidriai įkeliama pirmą kartą nuskaičius. Perduokite `new Engine(eager: true)`, kad kuriant būtų įdiegtos visos integruotos funkcijos — naudinga atitikties tikrinimo įrankiams, kurie tikrina deskriptorius prieš juos nuskaitant; įprastam įterpimui retai prireikia.

## Funkcijų iškvietimas iš PHP naudojant JS

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

`call()` ieško funkcijos pagal pavadinimą globaliajame objekte ir iškviečia ją su pateiktais PHP argumentais (automatiškai konvertuotais į JS reikšmes).

## PHP iškviečiamos funkcijos pateikimas kaip JS funkcijos

```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 uždarymai apgaubiami kaip JS funkcijos. Jų argumentai iškvietimo metu konvertuojami iš JS į PHP, o grąžinamos reikšmės konvertuojamos atgal iš PHP į JS.

## PHP objektai

PHP objektų dar negalima bendrinti su JavaScript. Susiejus `setGlobal()` su paprastu PHP objektu, susiejamas `undefined` (tai stebima per [ 18 problemą](https://github.com/inline0/phasis/issues/18)). Perduokite duomenis kaip masyvus, kurie nukopijuojami į JS, o elgseną pateikite kaip uždarymus:

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

Išsamią informaciją ir kitus sprendimo būdus rasite skiltyje [Bendrinami objektai](https://phasis.inline0.dev/lt/docs/interop/shared-objects).

## Išteklių ribos

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

`maxLoopIterations` (numatytoji reikšmė 100,000) yra vienintelis vykdymo metu keičiamas apribojimas; šiuo metu jis taikomas tik kodui, kurį vykdo medį interpretuojantis interpretatorius. Baitkodo VM vykdomos kilpos (funkcijų turiniai ir didžioji dalis aukščiausio lygio kodo) neskaičiuojamos, todėl vien šis apribojimas `while (true) {}` nesustabdo ([ 19 problema](https://github.com/inline0/phasis/issues/19)). Pasiekus apribojimą, klaidą galima pagauti JS; jei ji nepagauta, PHP gauna ją kaip `Phasis\Exceptions\InternalError`, kuri yra `Phasis\Exceptions\RuntimeError` poklasė.

Variklis taip pat turi fiksuotą 4,096 kadrų iškvietimų dėklo ribą (ir 8,192 kadrų apsaugą transpilintoms uždarosioms funkcijoms); ją viršijus išmetama „Maximum call stack size exceeded“ klaida, taip pat kaip `InternalError`. Laiko pagal sieninį laikrodį apribojimo nėra, todėl nepatikimą kodą vykdykite naudodami PHP nuosavą `max_execution_time` arba atskirame procese. Žr. [: setLimitAPI](https://phasis.inline0.dev/lt/docs/api#setlimit).

## Tolesni veiksmai

- [API žinynas](https://phasis.inline0.dev/lt/docs/api) — visa `Phasis\Engine` sąsaja.
- [Sąveika](https://phasis.inline0.dev/lt/docs/interop) — reikšmių konvertavimo taisyklės, pagrindinės funkcijos, PHP objektai.
- [Suderinamumas](https://phasis.inline0.dev/lt/docs/compatibility) — kas įgyvendinta, test262 aprėptis.
- [Analizatorius](https://phasis.inline0.dev/lt/docs/parser) ir [Formatavimo įrankis](https://phasis.inline0.dev/lt/docs/formatter) — analizuokite ir formatuokite JavaScript jo nevykdydami.
- [Išplėstinės temos](https://phasis.inline0.dev/lt/docs/advanced) — architektūra, baitkodo VM, našumo testai, tikrinimas pagal etaloninę realizaciją.
