انتقل إلى المحتوى

مخزن ملفات تعريف الارتباط

افتراضيًا، تتجاهل fetch() في Phasis ملفات تعريف الارتباط Set-Cookie الواردة في الاستجابات، ولا ترسل ترويسة Cookie في الطلبات. وهذا هو الإعداد المناسب للتضمين على الخادم؛ فعادةً لا تريد أن تؤثر استجابة مستخدم في طلب مستخدم آخر.

إذا كنت تحتاج إلى ملفات تعريف الارتباط — لتشغيل تدفق يعتمد على حالة الجلسة، أو الكشط بعد تسجيل الدخول، أو محاكاة سلوك المتصفح في الاختبارات — فأرفق مخزنًا باستخدام $engine->setCookieJar($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 وكذلك كائنات JsObject الموجودة في JS ذات الأعضاء المطابقة. يؤدي تمرير null إلى إفراغ المخزن.

يستدعي Phasis الدالة get(url) مرة لكل انتقال في الطلب (لذا تحصل التحويلات إلى مضيف مختلف على ملفات تعريف ارتباط حديثة)، ويستدعي set(url, line) مرة لكل ترويسة Set-Cookie في الاستجابة. تقع مسؤولية سياسة ملفات تعريف الارتباط — مطابقة النطاق وتحديد المسار وانتهاء الصلاحية وSameSite وSecure — على عاتق المخزن، لا Phasis.

مخزن داخل الذاكرة (للاختبارات)

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()));

مخزن من جهة JS

إذا كان مخزنك موجودًا في جهة JS — مثلًا لأنك تريد فحصه أو تعبئته مسبقًا من JavaScript — فاربطه عبر كائن JS:

JavaScript
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.

النطاق لكل طلب

يعيش المخزن ضمن الـ realm — ويستمر عبر كل fetch() إلى أن يُفرغ باستخدام setCookieJar(null). لتقييد المخزن بتدفق طلب واحد، افعل ذلك صراحةً:

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 — يعمل مخزن ملفات تعريف الارتباط داخل حلقة التحويل في Phasis، ومضافًا إلى أي ناقل ثبّتّه.
  • واجهات الويب (WPT) — اختبارات حزمة Fetch التي تغطي سلوك ملفات تعريف الارتباط.