Сессии и cookie
HTTP не помнит прошлых запросов. Чтобы сайт узнавал посетителя — хранил корзину, выбранный язык, тему оформления, — используют сессии и cookie. Сессия хранит данные на сервере, cookie — в браузере.
Запись и чтение сессии
Сессию получают из запроса:
#[Route('/visit', name: 'visit')]
public function visit(Request $request): Response
{
$session = $request->getSession();
$count = $session->get('visits', 0) + 1;
$session->set('visits', $count);
return new Response("Вы здесь уже $count раз");
}Второй аргумент get() — значение, если ключа ещё нет. Сессия запускается сама при первом обращении.
Методы сессии
| Метод | Что делает |
|---|---|
get('key', $default) | Читает значение |
set('key', $value) | Записывает |
has('key') | Проверяет наличие |
remove('key') | Удаляет одно значение |
clear() | Удаляет всё |
Корзина
В сессии можно хранить массивы:
#[Route('/cart/add/{id}', name: 'cart_add', methods: ['POST'])]
public function add(int $id, Request $request): Response
{
$session = $request->getSession();
$cart = $session->get('cart', []);
$cart[$id] = ($cart[$id] ?? 0) + 1;
$session->set('cart', $cart);
return $this->redirectToRoute('cart');
}Сессия в шаблоне и в сервисе
<p>Товаров в корзине: {{ app.session.get('cart', [])|length }}</p>В сервисе запроса под рукой нет — сессию берут через RequestStack:
use Symfony\Component\HttpFoundation\RequestStack;
class Cart
{
public function __construct(private RequestStack $requestStack) {}
public function items(): array
{
return $this->requestStack->getSession()->get('cart', []);
}
}Установка cookie
Cookie добавляют к ответу:
use Symfony\Component\HttpFoundation\Cookie;
#[Route('/theme/{name}', name: 'theme')]
public function theme(string $name): Response
{
$response = $this->redirectToRoute('home');
$response->headers->setCookie(
Cookie::create('theme', $name, new \DateTime('+1 year'))
);
return $response;
}Чтение и удаление cookie
$theme = $request->cookies->get('theme', 'light');
$response->headers->clearCookie('theme');Что выбрать
| Сессия | Cookie | |
|---|---|---|
| Где хранится | На сервере | В браузере |
| Может ли посетитель изменить | Нет | Да |
| Срок жизни | До закрытия браузера или дольше по настройке | Задаётся явно |
| Для чего | Корзина, шаги оформления | Тема, язык |
Частая ошибка
Cookie посетитель может прочитать и подделать. Нельзя хранить в них цену, роль или идентификатор пользователя и потом доверять этим значениям. Всё, что влияет на права и деньги, хранят на сервере — в сессии или в базе данных.