Представьте, что ваш сайт — это клуб, куда приходят разные люди. Кто-то просто смотрит, кто-то пишет посты, а кто-то модерирует. Yii2 помогает не запутаться: кто есть кто, и что кому можно делать. В этой статье разберем, как сделать так, чтобы каждый пользователь был на своем месте, а система работала как часы.
Почему многопользовательские системы — это вызов?
Когда на сайте один пользователь, всё просто: он залогинился, он же админ. Но как только появляется второй, начинаются вопросы. Как разделить данные? Как дать права на чтение, но не на запись? Как не перегрузить сервер, когда одновременно заходят 1000 человек?
Yii2 решает эти проблемы встроенными инструментами. Но важно понимать, как их правильно применить. Иначе получится как в том анекдоте: «Я сделал сайт с правами доступа, но теперь никто не может зайти».
База: пользователи, роли и разрешения
В Yii2 есть два подхода: простой (на базе компонента User) и продвинутый (с помощью RBAC). Давайте разберем оба.
Простой подход: все через User
Компонент User хранит информацию о текущем пользователе. Чтобы проверить, залогинен ли он, используем Yii::$app->user->isGuest. Чтобы узнать его ID — Yii::$app->user->id. Но этого мало для гибкого управления правами.
// Проверка, авторизован ли пользователь
if (!Yii::$app->user->isGuest) {
echo 'Привет, ' . Yii::$app->user->identity->username;
}
Продвинутый подход: RBAC (Role-Based Access Control)
RBAC — это система ролей и разрешений. Вы создаете роли (например, «админ», «модератор», «пользователь»), назначаете им разрешения (например, «редактировать пост», «удалять комментарий»), а потом привязываете роли к пользователям. Yii2 поддерживает это через расширение yii2-rbac.
// Настройка RBAC в конфигурации
'components' => [
'authManager' => [
'class' => 'yii\rbac\DbManager',
],
],
После настройки нужно создать таблицы в БД (миграция из коробки) и определить роли. Пример создания роли «admin»:
$auth = Yii::$app->authManager;
$admin = $auth->createRole('admin');
$auth->add($admin);
| Компонент | Описание | Пример использования |
|---|---|---|
| User | Текущий пользователь | Yii::$app->user->can('editPost') |
| AuthManager | Управление ролями и разрешениями | $auth->assign($role, $userId) |
| AccessControl | Фильтр для контроллеров | ['allow' => true, 'roles' => ['@']] |
Как не дать пользователям мешать друг другу?
Представьте, что два пользователя одновременно редактируют один и тот же пост. Что будет? Может получиться каша. Чтобы этого избежать, используйте блокировки или проверки версий.
Оптимистическая блокировка
Yii2 поддерживает optimistic locking — вы добавляете поле version в таблицу, и при сохранении проверяете, не изменилась ли запись. Если изменилась — выдается ошибка. Реализуется через поведение TimestampBehavior или вручную.
class Post extends \yii\db\ActiveRecord
{
public function optimisticLock()
{
return 'version';
}
}
Теперь, если два пользователя попытаются сохранить один пост, второй получит исключение.
Yii::$app->db->transaction.
Сессии и кэш: как не уронить сервер
Когда пользователей много, сессии и кэш становятся узким местом. По умолчанию Yii2 хранит сессии в файлах. Но при большом трафике лучше перенести их в Redis или базу данных.
// Конфигурация для хранения сессий в Redis
'components' => [
'session' => [
'class' => 'yii\redis\Session',
'redis' => [
'hostname' => 'localhost',
'port' => 6379,
],
],
],
Кэш тоже лучше вынести в Redis или Memcached. Это ускорит работу и снизит нагрузку на базу данных.
// Конфигурация кэша
'components' => [
'cache' => [
'class' => 'yii\redis\Cache',
'redis' => [
'hostname' => 'localhost',
'port' => 6379,
],
],
],
Пример: чат для нескольких пользователей
Давайте соберем всё вместе. Сделаем простой чат, где пользователи могут писать сообщения, а модераторы удалять их.
Шаг 1: Модель Message
namespace app\models;
use yii\db\ActiveRecord;
class Message extends ActiveRecord
{
public static function tableName()
{
return 'message';
}
public function rules()
{
return [
[['text', 'user_id'], 'required'],
['text', 'string', 'max' => 1000],
];
}
}
Шаг 2: Контроллер с проверкой прав
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\Message;
use yii\filters\AccessControl;
class MessageController extends Controller
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['create', 'delete'],
'rules' => [
[
'allow' => true,
'actions' => ['create'],
'roles' => ['@'], // только авторизованные
],
[
'allow' => true,
'actions' => ['delete'],
'roles' => ['moderator'], // только модераторы
],
],
],
];
}
public function actionCreate()
{
$model = new Message();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['index']);
}
return $this->render('create', ['model' => $model]);
}
public function actionDelete($id)
{
$model = Message::findOne($id);
if ($model && Yii::$app->user->can('deleteMessage')) {
$model->delete();
}
return $this->redirect(['index']);
}
}
Шаг 3: Настройка прав
// В контроллере или миграции
$auth = Yii::$app->authManager;
$deleteMessage = $auth->createPermission('deleteMessage');
$deleteMessage->description = 'Удаление сообщения';
$auth->add($deleteMessage);
$moderator = $auth->createRole('moderator');
$auth->add($moderator);
$auth->addChild($moderator, $deleteMessage);
Что в итоге?
Многопользовательские системы на Yii2 — это не rocket science. Главное — правильно настроить RBAC, использовать кэш и сессии с умом, и не забывать про блокировки. Начните с малого: добавьте роли, проверьте права в контроллерах, и постепенно усложняйте систему. Yii2 дает инструменты, а вы решаете, как их применить.
Помните: каждый пользователь — это личность. Дайте ему то, что он заслуживает, но не больше, чем нужно.

