
# Βάζο cookie

Από προεπιλογή, το `fetch()` του Phasis αγνοεί τα `Set-Cookie` από τις αποκρίσεις και δεν στέλνει κεφαλίδα `Cookie` στα αιτήματα. Αυτή είναι η σωστή προεπιλογή για ενσωμάτωση στην πλευρά του διακομιστή — συνήθως δεν θέλετε η απόκριση ενός χρήστη να επηρεάζει το αίτημα κάποιου άλλου.

Αν θέλετε cookies — για ροή που εξαρτάται από την κατάσταση συνεδρίας, συλλογή δεδομένων πίσω από σύνδεση ή αναπαραγωγή συμπεριφοράς προγράμματος περιήγησης σε δοκιμές — προσαρτήστε ένα jar με το `$engine->setCookieJar($jar)`.

## Η διεπαφή

Το jar μπορεί να είναι οποιοδήποτε αντικείμενο υλοποιεί δύο μεθόδους:

```
get(url: string): string         // returns a "Cookie:" header value, e.g. "sid=abc; pref=dark"
set(url: string, header: string): void   // receives one Set-Cookie line
```

Λειτουργούν τόσο αντικείμενα PHP όσο και JS-side `JsObject`s με τα αντίστοιχα μέλη. Αν περάσετε `null`, το jar εκκαθαρίζεται.

Το Phasis καλεί το `get(url)` μία φορά ανά βήμα αιτήματος (ώστε οι ανακατευθύνσεις σε διαφορετικό host να λαμβάνουν νέα cookies) και το `set(url, line)` μία φορά για κάθε κεφαλίδα `Set-Cookie` στην απόκριση. Η *πολιτική* cookies — αντιστοίχιση domain, περιορισμός διαδρομής, λήξη, `SameSite`, `Secure` — είναι ευθύνη του jar, όχι του Phasis.

## Jar στη μνήμη (δοκιμές)

```php
final class MemoryJar
{
    /** @var array<string, array<string, string>> host → name → "name=value" */
    private array $store = [];

    public function get(string $url): string
    {
        $host = parse_url($url, PHP_URL_HOST) ?? '';
        return implode('; ', $this->store[$host] ?? []);
    }

    public function set(string $url, string $header): void
    {
        $host = parse_url($url, PHP_URL_HOST) ?? '';
        [$nv] = explode(';', $header, 2);
        [$name, $value] = explode('=', trim($nv), 2) + ['', ''];
        if ($name !== '') {
            $this->store[$host][$name] = "$name=$value";
        }
    }
}

$engine->setCookieJar(new MemoryJar());
```

Αυτό αρκεί για μια δοκιμαστική διάταξη επιτυχούς διαδρομής, αλλά αγνοεί τα `Domain=`, `Path=`, `Expires=` και τα γνωρίσματα `Secure`/`HttpOnly`/`SameSite`. Μην το χρησιμοποιείτε σε περιπτώσεις που διασχίζουν όριο εμπιστοσύνης.

## Symfony BrowserKit

Αν έχετε ήδη εγκαταστήσει τις βιβλιοθήκες HTTP του Symfony, το `BrowserKit\CookieJar` χειρίζεται σωστά την πολιτική.

```php
use Symfony\Component\BrowserKit\CookieJar as BrowserCookieJar;
use Symfony\Component\BrowserKit\Cookie;

final class SymfonyJarAdapter
{
    public function __construct(private BrowserCookieJar $jar) {}

    public function get(string $url): string
    {
        $cookies = $this->jar->allValues($url);
        return implode('; ', array_map(
            fn ($n, $v) => "$n=$v",
            array_keys($cookies),
            array_values($cookies),
        ));
    }

    public function set(string $url, string $header): void
    {
        $cookie = Cookie::fromString($header, $url);
        $this->jar->set($cookie);
    }
}

$engine->setCookieJar(new SymfonyJarAdapter(new BrowserCookieJar()));
```

## Jar στην πλευρά του JS

Αν το jar σας βρίσκεται στην πλευρά του JS — για παράδειγμα, επειδή θέλετε να το ελέγχετε ή να το αρχικοποιείτε από το JavaScript — συνδέστε το μέσω αντικειμένου JS:

```js
const jar = new Map();
$jar.get = (url) => Array.from(jar.entries()).map(([k, v]) => `${k}=${v}`).join('; ');
$jar.set = (url, header) => {
  const [nv] = header.split(';');
  const [name, value] = nv.split('=');
  jar.set(name.trim(), value.trim());
};
```

```php
$engine->eval($script);
$engine->setCookieJar($engine->eval('$jar'));
```

Καλούνται οι ίδιες μέθοδοι `get`/`set`, είτε ο δέκτης είναι αντικείμενο PHP είτε `JsObject`.

## Εμβέλεια ανά αίτημα

Ένα jar ζει στο realm — διατηρείται σε κάθε `fetch()` μέχρι να εκκαθαριστεί με `setCookieJar(null)`. Για να περιορίσετε ένα jar σε μία μόνο ροή αιτημάτων, κάντε το ρητά:

```php
$engine->setCookieJar($jar);
$engine->eval('await runLoginFlow()');
$engine->setCookieJar(null);
```

## Επιθεώρηση από το PHP

Το `$engine->getCookieJar()` επιστρέφει ό,τι του δόθηκε — χρήσιμο για ελέγχους σε δοκιμές.

```php
$jar = new MemoryJar();
$engine->setCookieJar($jar);
$engine->eval('await fetch("https://api.example.com/login", { method: "POST" })');

assertNotEmpty($engine->getCookieJar()->get('https://api.example.com/'));
```

## Δείτε επίσης

- [Μεταφορά Fetch](https://phasis.inline0.dev/el/docs/interop/fetch-transport) — το cookie jar λειτουργεί **μέσα** στον βρόχο ανακατευθύνσεων του Phasis, πάνω από όποια μεταφορά έχετε εγκαταστήσει.
- [Web APIs (WPT)](https://phasis.inline0.dev/el/docs/compatibility/web-apis) — οι δοκιμές Fetch Pack που καλύπτουν τη συμπεριφορά των cookies.
