
# Začíname

## Inštalácia

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

Phasis vyžaduje PHP 8.2 alebo novší a tri rozšírenia, ktoré všetky vyžaduje `composer.json`:

- `mbstring` — práca s reťazcami.
- `bcmath` — aritmetika BigInt a spracovanie čísel s celočíselnou presnosťou.
- `curl` — predvolený prenosový mechanizmus pre `fetch()`.

`mbstring` a `curl` sú povolené vo väčšine zostáv. `bcmath` často chýba: oficiálne obrazy `php` Docker (`php:8.x-cli`, `php:8.x-fpm`) ho neobsahujú a niektoré distribúcie ho balia samostatne (`php-bcmath`). Bez neho Composer odmietne nainštalovať Phasis. Do Dockerfile založeného na oficiálnom obraze pridajte:

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

Spustite `php -m` a zistite, ktoré rozšírenia obsahuje vaša zostava.

`ext-intl` je voliteľné. Phasis funguje aj bez neho, ale celá rodina `Intl.*` (`Collator`, `NumberFormat`, `DateTimeFormat`, `PluralRules`, `Locale`, `DisplayNames`, `ListFormat`, `RelativeTimeFormat`, `Segmenter`, `DurationFormat`) a kalendáre Temporal, ktoré nie sú ISO (`hebrew`, `islamic`, `japanese`, `persian` atď.), ho potrebujú. Nainštalujte ho vždy, keď hostiteľská aplikácia poskytuje JS pracujúce s formátovaním závislým od miestnych nastavení. Voliteľné je aj `ext-openssl`: šifrovanie AES-CBC, AES-CTR a AES-GCM cez `crypto.subtle` ho vyžaduje, kým súhrny a HMAC fungujú aj bez neho.

Bez `exec`, bez FFI, bez Node.js, bez vlastného natívneho rozšírenia.

## Spustenie skriptu z 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 vypíše to, čo skript zapisuje pomocou `console.log`; hodnotu posledného výrazu nevypíše.

Úplný zoznam príkazov nájdete v [referenčnej príručke CLI](https://phasis.inline0.dev/sk/docs/cli).

## Vloženie do 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
```

Inštancia `Engine` si medzi volaniami zachováva globálny stav, takže pri ďalších volaniach `eval()` budú k dispozícii všetky predtým definované prvky.

`console.log` a súvisiace funkcie pridávajú obsah do vyrovnávacej pamäte modulu namiesto zapisovania na stdout. Prečítajte ho pomocou `getConsoleOutput()` (jeden reťazec, riadky spojené pomocou `\n`) alebo `getConsoleLines()` (zoznam riadkov) a vymažte ho pomocou `clearConsole()`.

Studený štart je rýchly: vopred sa nainštaluje iba jadro potrebné na načítanie špecifikácie (`Object`, `Function`, `Array`, `Promise`, `Symbol`, `BigInt`, `RegExp` a typy chýb). `Map`, `TypedArray`, `Temporal`, `Intl`, `URL`, `fetch`, úplné balíky Web Platform / Fetch aj všetko ostatné sa transparentne vytvoria pri prvom čítaní. Ak chcete pri vytváraní nainštalovať všetky vstavané prvky, odovzdajte `new Engine(eager: true)` — užitočné pre nástroje na kontrolu zhody, ktoré skúmajú deskriptory ešte pred čítaním; pri bežnom vkladacom použití je to zriedka potrebné.

## Volanie funkcií JS z PHP

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

`call()` vyhľadá funkciu podľa názvu na globálnom objekte a zavolá ju s dodanými argumentmi PHP (automaticky prevedenými na hodnoty JS).

## Sprístupnenie volateľnej funkcie PHP ako funkcie 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")');
```

Uzávery PHP sa zabalia ako funkcie JS. Ich argumenty sa pri volaní prevedú z JS na PHP a návratové hodnoty sa prevedú späť z PHP na JS.

## Objekty PHP

Objekty PHP zatiaľ nemožno zdieľať s JavaScript. `setGlobal()` s obyčajným objektom PHP naviaže `undefined` (sledované v [probléme č. 18](https://github.com/inline0/phasis/issues/18)). Údaje odovzdávajte ako polia, ktoré sa skopírujú do JS, a správanie sprístupnite ako uzávery:

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

Podrobnosti a ďalšie riešenia nájdete v časti [Zdieľané objekty](https://phasis.inline0.dev/sk/docs/interop/shared-objects).

## Limity zdrojov

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

`maxLoopIterations` (predvolená hodnota 100,000) je jediný limit nastaviteľný počas behu programu a momentálne sa vzťahuje len na kód spúšťaný interpretom prechádzajúcim strom. Slučky spúšťané VM bajtkódu (telá funkcií a väčšina kódu najvyššej úrovne) sa nezapočítavajú, takže samotný limit nezastaví `while (true) {}` ([problém č. 19](https://github.com/inline0/phasis/issues/19)). Po dosiahnutí limitu možno chybu zachytiť v JS; ak zostane nezachytená, dostane sa do PHP ako `Phasis\Exceptions\InternalError`, podtrieda `Phasis\Exceptions\RuntimeError`.

Modul má tiež pevný limit zásobníka volaní 4,096 rámcov (a ochranný limit 8,192 rámcov pre transpilované uzávery); jeho prekročenie vyvolá chybu „Maximum call stack size exceeded“, opäť ako `InternalError`. Časový limit v reálnom čase neexistuje, preto nedôveryhodný kód spúšťajte pod vlastným `max_execution_time` nástroja PHP alebo v samostatnom procese. Pozrite si [API: setLimit](https://phasis.inline0.dev/sk/docs/api#setlimit).

## Ďalšie kroky

- [API referencia](https://phasis.inline0.dev/sk/docs/api) — úplné rozhranie `Phasis\Engine`.
- [Prepojenie](https://phasis.inline0.dev/sk/docs/interop) — pravidlá konverzie hodnôt, hostiteľské funkcie, objekty PHP.
- [Kompatibilita](https://phasis.inline0.dev/sk/docs/compatibility) — implementované funkcie a pokrytie test262.
- [Analyzátor](https://phasis.inline0.dev/sk/docs/parser) a [Formátovač](https://phasis.inline0.dev/sk/docs/formatter) — analyzovanie a formátovanie JavaScript bez jeho spustenia.
- [Rozšírené témy](https://phasis.inline0.dev/sk/docs/advanced) — architektúra, VM bajtkódu, testy výkonu a testovanie pomocou referenčnej implementácie.
