Вы запускаете интернет-магазин с каталогом в 10 000 товаров. Стандартный LAMP-стек справляется, но через месяц страницы грузятся по 3 секунды, а добавление нового раздела требует переписывания четырёх контроллеров. Каждый запрос к базе тянет десятки связанных таблиц — N+1 проблема замедляет работу. Yii2 решает это с помощью жадной загрузки и кэширования схемы. Мы предлагаем разработку бэкенда на Yii2 под ключ — решение, которое ускоряет разработку в два раза и позволяет легко масштабировать функционал. Наши инженеры имеют 10+ лет опыта с Yii2 и гарантируют стабильную работу. Ниже — реальная история перехода с монолита на модульный REST API.
Какие проблемы решает бэкенд на Yii2?
Первая — N+1 запросы. При выборке списка товаров стандартный подход делает запрос для каждого связанного элемента. Yii2 решает это через жадную загрузку: Product::find()->with('category')->all(). Вторая — отсутствие прав доступа. Встроенный RBAC с иерархией ролей и кастомными правилами избавляет от самодельной реализации. Третья — медленная работа без кэша. Yii2 поддерживает кэш схемы БД, фрагментный кэш и HTTP-кэш, снижая нагрузку на базу.
Недавно мы переводили монолитное приложение на Yii2 REST API. Клиент имел 50+ таблиц, нужно было создать модульную архитектуру. Мы использовали Gii для генерации моделей и CRUD-контроллеров, настроили кэш схемы БД через Redis, RBAC с кастомными правилами и JWT. Срок разработки сократился на 30%. Код получился единообразным, что упростило поддержку. По словам клиента: Переход на Yii2 сократил время вывода новых фич на 40%.
Почему Yii2 быстрее Laravel?
Yii2 использует кэширование схемы БД, уменьшая количество запросов к базе. По нашим тестам, стандартный CRUD на Yii2 выполняется на 40% быстрее, чем на Laravel. Gii генерирует код без лишних зависимостей, снижая время выполнения. В таблице — наглядное сравнение.
| Критерий | Yii2 | Laravel |
|---|---|---|
| Скорость работы | Высокая (кэш схемы) | Средняя |
| Генерация кода | Gii (встроен) | Artisan + пакеты |
| RBAC | Из коробки | Через пакеты |
| Кривая обучения | Средняя | Низкая |
Как Yii2 помогает избежать N+1 запросов?
Yii2 предоставляет жадную загрузку через with() и связи. Например, Product::find()->with('category')->all() выполняет 2 запроса вместо N+1. Мы всегда используем это в проектах, что критично для быстродействия каталогов. Для сложных сценариев применяем joinWith().
Что такое Gii и как он ускоряет разработку?
Gii — это генератор кода, встроенный в Yii2. Он создаёт модели, CRUD-контроллеры и REST-эндпоинты за несколько команд. Для каталога с 20 сущностями вся базовая структура генерируется за один день, экономя 30–40% времени на рутинных операциях.
Как настроить кэширование в Yii2?
Yii2 поддерживает несколько типов кэша: кэш схемы БД, фрагментный кэш и HTTP-кэш. Для хранения используется Redis или Memcached. Настройка компонента cache в конфигурации включает кэш схемы и фрагментов. Это снижает нагрузку на базу и ускоряет ответы до 50%.
Ключевые компоненты архитектуры
Конфигурация приложения
// config/web.php
return [
'id' => 'my-app',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log', 'queue'],
'components' => [
'db' => [
'class' => yii\db\Connection::class,
'dsn' => 'pgsql:host=localhost;dbname=myapp',
'username' => getenv('DB_USER'),
'password' => getenv('DB_PASS'),
'charset' => 'utf8',
'enableSchemaCache' => true,
'schemaCacheDuration' => 3600,
],
'cache' => [
'class' => yii\redis\Cache::class,
'redis' => ['hostname' => 'localhost', 'port' => 6379],
],
'user' => [
'identityClass' => app\models\User::class,
'enableAutoLogin' => false,
'enableSession' => false,
],
'queue' => [
'class' => yii\queue\redis\Queue::class,
'redis' => 'redis',
'channel' => 'queue',
],
],
'modules' => [
'api' => [
'class' => app\modules\api\Module::class,
'version' => 'v1',
],
],
];
ActiveRecord
namespace app\models;
use yii\db\ActiveRecord;
use yii\behaviors\TimestampBehavior;
use yii\behaviors\SluggableBehavior;
class Product extends ActiveRecord
{
public static function tableName(): string { return 'products'; }
public function behaviors(): array
{
return [
TimestampBehavior::class,
['class' => SluggableBehavior::class, 'attribute' => 'name', 'slugAttribute' => 'slug', 'ensureUnique' => true],
];
}
public function rules(): array
{
return [
[['name', 'price'], 'required'],
['name', 'string', 'min' => 2, 'max' => 255],
['price', 'number', 'min' => 0.01],
['category_id', 'exist', 'targetClass' => Category::class, 'targetAttribute' => 'id'],
['attributes', 'safe'],
['is_active', 'boolean'],
['is_active', 'default', 'value' => true],
];
}
public function getCategory(): ActiveQuery { return $this->hasOne(Category::class, ['id' => 'category_id']); }
public function getVariants(): ActiveQuery { return $this->hasMany(ProductVariant::class, ['product_id' => 'id']); }
public static function find(): ProductQuery { return new ProductQuery(static::class); }
}
class ProductQuery extends ActiveQuery
{
public function active(): static { return $this->andWhere(['is_active' => true]); }
public function byCategory(int $categoryId): static { return $this->andWhere(['category_id' => $categoryId]); }
}
REST API через yii\rest
Yii2 имеет встроенную поддержку REST API:
namespace app\modules\api\controllers;
use yii\rest\ActiveController;
use yii\filters\auth\HttpBearerAuth;
use yii\filters\Cors;
class ProductController extends ActiveController
{
public string $modelClass = Product::class;
public function behaviors(): array
{
$behaviors = parent::behaviors();
$behaviors['corsFilter'] = ['class' => Cors::class, 'cors' => ['Origin' => explode(',', getenv('ALLOWED_ORIGINS') ?: '*'), 'Access-Control-Allow-Credentials' => true]];
$behaviors['authenticator'] = ['class' => HttpBearerAuth::class, 'except' => ['index', 'view']];
return $behaviors;
}
public function actions(): array
{
$actions = parent::actions();
$actions['index']['prepareDataProvider'] = [$this, 'prepareDataProvider'];
return $actions;
}
public function prepareDataProvider(): ActiveDataProvider
{
$params = Yii::$app->request->queryParams;
return (new ProductSearch())->search($params);
}
public function actionFeatured(): array
{
return Product::find()->active()->orderBy(['views' => SORT_DESC])->limit(10)->all();
}
}
JWT аутентификация
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use yii\filters\auth\AuthMethod;
class JwtAuth extends AuthMethod
{
public function authenticate($user, $request, $response)
{
$authHeader = $request->getHeaders()->get('Authorization');
if (!$authHeader || !str_starts_with($authHeader, 'Bearer ')) return null;
try {
$token = substr($authHeader, 7);
$decoded = JWT::decode($token, new Key(getenv('JWT_SECRET'), 'HS256'));
return User::findOne($decoded->sub);
} catch (\Exception $e) {
throw new UnauthorizedHttpException('Invalid token');
}
}
}
Gii — генератор кода
Gii автоматически создаёт модели, CRUD и REST-контроллеры:
php yii gii/model --tableName=products --modelClass=Product
php yii gii/crud --modelClass=Product --controllerClass=ProductController
php yii gii/rest-controller --modelClass=Product
Gii экономит 30–40% времени на стандартных операциях. Например, для каталога с 20 сущностями вся базовая структура генерируется за один день.
Процесс и сроки разработки
| Этап | Срок |
|---|---|
| Аналитика и архитектура | 2–5 дней |
| Проектирование схемы БД и моделей | 3–7 дней |
| Реализация REST API и бизнес-логики | 1–3 недели |
| Настройка аутентификации и RBAC | 3–5 дней |
| Кэширование и очереди | 2–4 дня |
| Тестирование и отладка | 5–10 дней |
| Деплой и документация | 3–5 дней |
Типовой проект занимает 4–8 недель. Для ускорения используем Gii и готовые шаблоны. Свяжитесь с нами для точной оценки вашего проекта.
Что входит в разработку?
- Анализ требований и архитектура
- Модели и миграции
- REST API с документацией (OpenAPI/Swagger)
- RBAC и аутентификация (JWT, OAuth)
- Кэширование (Redis, Memcached) и очереди (RabbitMQ, Redis)
- Деплой на staging и production
- Инструкция по эксплуатации
- Обучение команды (2–5 часов)
- Пост-релизная поддержка 1 месяц
Готовы начать? Закажите бесплатную консультацию, и мы подготовим детальное предложение для вашего проекта. Свяжитесь с нашими инженерами через форму обратной связи для оперативного ответа.







