Куки

Куки — второй, помимо сессии, слой данных, который у каждого посетителя свой. В отличие от сессии они переживают закрытие браузера и не требуют серверного хранилища, поэтому в них держат долгоживущие мелочи: выбранный город, версию витрины, метку рекламной кампании.

Запись, чтение, удаление

// Записать на 30 дней
MELBIS()->CookieSet('town', $town, 30);

// Прочитать (вернёт пустую строку, если куки нет)
$town = MELBIS()->CookieGet('town');

// Удалить
MELBIS()->CookieClear('town');

Полная сигнатура записи:

CookieSet($mName, $mValue, $mLifeDay = 0, $mPath = "/", $mDomain = '', $mSecure = true, $mHttpOnly = false)

Время жизни задаётся в днях; 0 означает cookie на время сессии браузера.

CookieSet и CookieClear сразу обновляют $_COOKIE, так что записанное значение доступно в том же запросе, не дожидаясь следующего.

Атрибуты безопасности

Два атрибута выставляются движком принудительно: SameSite=Lax — cookie не уходит на сторонние межсайтовые запросы, но переживает возврат посетителя по обычной ссылке, например с платёжного шлюза. И Secure — по умолчанию true, последним обязательным аргументом его можно снять для локальной работы по http.

HttpOnly — последний аргумент, по умолчанию выключен. Флаг прячет значение от document.cookie: браузерный скрипт такую куку не прочитает и не перезапишет, хотя на сервер она по-прежнему ходит в каждом запросе и CookieGet видит её как обычно.

Включать его нужно там, где в куке лежит секрет — токен автологина, ключ доступа, что угодно, чем можно воспользоваться от имени посетителя. Тогда зловредный скрипт, попавший на страницу через XSS, не сможет вычитать значение и угнать сессию:

// Автологин: значение не должно быть доступно скриптам
MELBIS()->CookieSet('client_secret', $secret, 90, '/', '.'.$domain, true, true);

Для обычных настроек — выбранный город, версия витрины, свёрнутый баннер — флаг не нужен и только мешает: такие значения часто читает и пишет сам клиент.

У куки должен быть один хозяин. Перезаписать HttpOnly-куку из JavaScript нельзя: браузер молча игнорирует присваивание — ни ошибки, ни предупреждения, значение просто не меняется. Обратное разрешено, сервер перезапишет и погасит любую куку. Поэтому решите заранее, кто ведёт конкретную куку: если её пишет клиентский скрипт, серверный CookieSet с тем же именем вызывать нельзя — один такой вызов сломает клиентскую запись у всех, кто успел получить куку с флагом.

Куки и кеш

Как и значения из сессии, содержимое куки нельзя выводить обычной переменной модуля, у которого включён кеш: первое же значение запечётся в кеш и достанется остальным посетителям. Персональные данные передаются в вёрстку только через глобальный массив (см. «Глобальный массив»).