Вы когда-нибудь пытались сделать интернет-магазин на коленке за выходные? Я да. И знаете что? Получилось. Но не сразу. В этой статье я расскажу, как я использовал Yii2 для создания полноценного магазина, и поделюсь граблями, на которые наступил. Если вы тоже хотите собрать свой онлайн-бутик, но боитесь сложностей — читайте дальше. Будет просто и с примерами.
Почему Yii2, а не Laravel или Symfony
Когда я выбирал фреймворк, у меня было три кандидата: Laravel, Symfony и Yii2. Laravel — красивый, но для магазина показался тяжеловатым. Symfony — мощный, но слишком много конфигурации. Yii2 же — как швейцарский нож: легкий, быстрый, и в нем уже есть Gii — генератор кода. Это спасло мне кучу времени. Не надо писать CRUD вручную. Нажал пару кнопок — и модель готова.
Вот таблица для сравнения:
| Параметр | Yii2 | Laravel | Symfony |
|---|---|---|---|
| Скорость старта | Высокая (Gii, готовые модули) | Средняя (нужно настроить многое) | Низкая (много boilerplate) |
| Производительность | Отличная (ленивая загрузка) | Хорошая | Отличная |
| Гибкость | Средняя (но для магазина хватает) | Высокая | Очень высокая |
| Сообщество | Маленькое, но активное | Огромное | Большое |
Вывод: для небольшого или среднего магазина Yii2 — идеальный вариант. Он не перегружен, но дает все необходимое.
Структура проекта: с чего начать
Первым делом я установил Yii2 через Composer. Команда простая:
composer create-project --prefer-dist yiisoft/yii2-app-basic shopПотом настроил базу данных. Я использовал MySQL, но можно и PostgreSQL. В конфиге config/db.php прописал подключение:
<?php
return [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=shop',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
];Дальше — модели и контроллеры. С помощью Gii я сгенерировал модели для товаров, категорий и заказов. Это заняло 10 минут. Потом добавил связи: товар belongsTo категории, заказ hasMany товаров.
Корзина: как не запутаться в сессиях
Корзина — сердце магазина. Я решил хранить ее в сессии, чтобы не грузить базу лишний раз. Создал компонент Cart:
<?php
namespace app\components;
use Yii;
use app\models\Product;
class Cart
{
public function add($productId, $quantity = 1)
{
$session = Yii::$app->session;
$cart = $session->get('cart', []);
if (isset($cart[$productId])) {
$cart[$productId] += $quantity;
} else {
$cart[$productId] = $quantity;
}
$session->set('cart', $cart);
}
public function getItems()
{
$session = Yii::$app->session;
$cart = $session->get('cart', []);
$items = [];
foreach ($cart as $id => $qty) {
$product = Product::findOne($id);
if ($product) {
$items[] = [
'product' => $product,
'quantity' => $qty,
];
}
}
return $items;
}
public function clear()
{
Yii::$app->session->remove('cart');
}
}В контроллере вызывал Yii::$app->cart->add($id). Просто и понятно. Но есть нюанс: сессии не работают, если не включены куки. Проверьте настройки в config/web.php.
Ajax-обновление корзины: делаем без перезагрузки
Чтобы корзина обновлялась динамически, я добавил немного JavaScript. Вот как это выглядит на фронте:
$(document).on('click', '.add-to-cart', function() {
var productId = $(this).data('id');
$.ajax({
url: '/cart/add',
method: 'POST',
data: {id: productId},
success: function(response) {
$('#cart-count').text(response.count);
alert('Товар добавлен в корзину');
}
});
});А в контроллере Yii2 обрабатываем запрос:
public function actionAdd()
{
$id = Yii::$app->request->post('id');
Yii::$app->cart->add($id);
return json_encode(['count' => count(Yii::$app->cart->getItems())]);
}Только не забудьте подключить jQuery и настроить CSRF-защиту. В Yii2 это делается через мета-тег в шаблоне:
<head>
<meta name="csrf-token" content="<?= Yii::$app->request->csrfToken ?>">
</head>Оформление заказа: валидация и сохранение
Когда пользователь кликает «Оформить заказ», я создаю модель Order и сохраняю данные. Вот упрощенный код:
<?php
namespace app\models;
use yii\db\ActiveRecord;
class Order extends ActiveRecord
{
public static function tableName()
{
return 'orders';
}
public function rules()
{
return [
[['customer_name', 'customer_email', 'address'], 'required'],
['customer_email', 'email'],
['status', 'default', 'value' => 'new'],
];
}
public function getItems()
{
return $this->hasMany(OrderItem::class, ['order_id' => 'id']);
}
}В контроллере оформления:
public function actionCheckout()
{
$order = new Order();
if ($order->load(Yii::$app->request->post()) && $order->validate()) {
$order->save();
// Сохраняем товары из корзины в order_items
foreach (Yii::$app->cart->getItems() as $item) {
$orderItem = new OrderItem();
$orderItem->order_id = $order->id;
$orderItem->product_id = $item['product']->id;
$orderItem->quantity = $item['quantity'];
$orderItem->price = $item['product']->price;
$orderItem->save();
}
Yii::$app->cart->clear();
Yii::$app->session->setFlash('success', 'Заказ оформлен!');
return $this->redirect(['site/index']);
}
return $this->render('checkout', ['model' => $order]);
}Yii::$app->db->transaction.Что в итоге
Мы разобрали базовый интернет-магазин на Yii2: установку, структуру, корзину, Ajax и оформление заказа. Этого достаточно, чтобы запустить MVP. Дальше можно добавить админку, платежные системы, email-уведомления. Yii2 дает гибкость, но не заставляет писать лишнего. Если вы новичок — не бойтесь. Просто делайте шаг за шагом. И помните: код должен быть читаемым, а не гениальным.
Студия WNDER


