Ответ
Понимание архитектуры корзины — это не только про добавление товаров в сессию, но и про выбор стратегии хранения, консистентность данных и интеграцию с другими системами. Вот как я подхожу к этому:
1. Выбор стратегии хранения (зависит от требований):
- Сессии (
$_SESSION): Для простых случаев, где корзина живет только в рамках одной браузерной сессии. Быстро, но не масштабируется и теряется при очистке кэша. - База данных: Для постоянных корзин, доступных с разных устройств. Требует таблицы
cartиcart_items, связь с пользователем. - Кэш (Redis/Memcached): Идеально для высокой нагрузки. Хранит структурированные данные (например, хэш
cart:user:123) с TTL. Я часто использую этот подход.
2. Проектирование модели данных: Корзина — это не просто список ID, а агрегат с собственной бизнес-логикой (проверка наличия, применение скидок).
Пример сущности на PHP (упрощенно):
class Cart {
private string $id;
private array $items = []; // ['product_id' => CartItem]
private ?string $couponCode = null;
public function addItem(Product $product, int $quantity): void {
$key = $product->getId();
if (isset($this->items[$key])) {
$this->items[$key]->increaseQuantity($quantity);
} else {
$this->items[$key] = new CartItem($product, $quantity);
}
$this->recalculateTotal();
}
private function recalculateTotal(): void {
$this->total = array_sum(array_map(
fn(CartItem $item) => $item->getSubtotal(),
$this->items
));
// Применение скидки, налогов и т.д.
}
}
3. Ключевые архитектурные вопросы:
- Консистентность цен: Цена должна фиксироваться на момент добавления в корзину или пересчитываться при оформлении заказа? Я реализовывал оба подхода, фиксация предпочтительнее.
- Интеграция с инвентарем: Нужна ли проверка наличия товара в реальном времени при каждом изменении корзины? Чаще это делается на этапе checkout.
- Очистка: Реализация джобов для очистки заброшенных корзин из БД или кэша.
Понимание этих аспектов позволяет выбрать между готовым решением (вроде корзины в Sylius) и кастомной реализацией.