Маршрутизация с PHP атрибутами
PHP атрибуты предоставляют чистую, основанную на декораторах альтернативу определению маршрутов с использованием фасада TelegramRouter. Этот подход размещает определения маршрутов близко к методам-обработчикам, улучшая организацию и читаемость кода.
Вместо регистрации маршрутов через фасад:
TelegramRouter::onCommand('/start', function(CommandData $data) { // Обработка команды /start});Вы можете определять маршруты, используя атрибуты прямо на методах контроллера:
#[OnCommand('/start')]public function handleStart(CommandData $data) { // Обработка команды /start}Начало работы
Заголовок раздела «Начало работы»Базовое использование
Заголовок раздела «Базовое использование»Создайте класс контроллера и украсьте методы атрибутами маршрутизации:
<?php
namespace App\Telegram\Handlers;
use HybridGram\Core\Routing\Attributes\OnCommand;use HybridGram\Core\Routing\Attributes\OnTextMessage;use HybridGram\Core\Routing\RouteData\CommandData;use HybridGram\Core\Routing\RouteData\TextMessageData;
class BotHandler{ #[OnCommand('/start')] public function handleStart(CommandData $data): void { $telegram = app(\HybridGram\Telegram\TelegramBotApi::class); $telegram->sendMessage($data->getChat()->id, 'Добро пожаловать!'); }
#[OnTextMessage] public function handleMessage(TextMessageData $data): void { // Обработка всех текстовых сообщений }}Регистрация
Заголовок раздела «Регистрация»Маршруты, определённые с атрибутами, автоматически обнаруживаются и регистрируются при загрузке приложения. Фреймворк сканирует классы приложения и регистрирует любые маршруты, определённые с помощью атрибутов маршрутизации.
Чтобы включить маршрутизацию на основе атрибутов, убедитесь, что AttributeRouteRegistrar вызывается в поставщике услуг или файле загрузки приложения.
Доступные атрибуты
Заголовок раздела «Доступные атрибуты»Обработка сообщений
Заголовок раздела «Обработка сообщений»OnTextMessage
Заголовок раздела «OnTextMessage»Обработка текстовых сообщений:
#[OnTextMessage]public function handleMessage(TextMessageData $data): void { // Обработка всех текстовых сообщений}
#[OnTextMessage(pattern: 'привет')]public function handleGreeting(TextMessageData $data): void { // Обработка сообщений содержащих 'привет'}OnCommand
Заголовок раздела «OnCommand»Обработка команд Telegram:
#[OnCommand('/start')]public function handleStart(CommandData $data): void { // Обработка команды /start}
#[OnCommand('/user:*')]public function handleUserCommand(CommandData $data): void { // Обработка /user:* с параметрами}OnCallbackQuery
Заголовок раздела «OnCallbackQuery»Обработка нажатий на кнопки:
#[OnCallbackQuery(pattern: 'menu:*')]public function handleMenuCallback(CallbackQueryData $data): void { // Обработка callback запросов типа 'menu:home'}Обработка медиа
Заголовок раздела «Обработка медиа»Обработка различных типов медиа:
#[OnPhoto]public function handlePhoto(PhotoData $data): void {}
#[OnDocument]public function handleDocument(DocumentData $data): void {}
#[OnAudio]public function handleAudio(AudioData $data): void {}
#[OnVideo]public function handleVideo(VideoData $data): void {}
#[OnVoice]public function handleVoice(VoiceData $data): void {}
#[OnLocation]public function handleLocation(LocationData $data): void {}
#[OnContact]public function handleContact(ContactData $data): void {}События участников чата
Заголовок раздела «События участников чата»#[OnChatMember]public function handleChatMember(ChatMemberUpdatedData $data): void {}
#[OnMyChatMember]public function handleBotChatMember(ChatMemberUpdatedData $data): void {}Другие события
Заголовок раздела «Другие события»#[OnPoll]public function handlePoll(PollData $data): void {}
#[OnInlineQuery]public function handleInlineQuery(InlineQueryData $data): void {}
#[OnAny]public function handleAny(UpdateData $data): void {}
#[OnFallback]public function handleFallback(FallbackData $data): void {}Фильтрация и условия
Заголовок раздела «Фильтрация и условия»Типы чатов
Заголовок раздела «Типы чатов»Ограничьте маршруты определённой типа чатов:
use HybridGram\Core\Routing\Attributes\ChatTypes;use HybridGram\Core\Routing\ChatType;
#[OnCommand('/admin')]#[ChatTypes([ChatType::PRIVATE, ChatType::GROUP])]public function handleAdminCommand(CommandData $data): void { // Работает только в приватных чатах и группах}Выбор бота
Заголовок раздела «Выбор бота»Нацельтесь на конкретные боты:
use HybridGram\Core\Routing\Attributes\ForBot;
#[OnCommand('/start')]#[ForBot('main')]public function handleStart(CommandData $data): void { // Только для бота 'main'}Middleware
Заголовок раздела «Middleware»Применяйте middleware к маршрутам:
use HybridGram\Core\Routing\Attributes\TgMiddlewares;use App\Telegram\Middleware\AuthMiddleware;
#[OnCommand('/admin')]#[TgMiddlewares([AuthMiddleware::class])]public function handleAdmin(CommandData $data): void { // AuthMiddleware выполняется перед этим обработчиком}Маршрутизация на основе состояния пользователя
Заголовок раздела «Маршрутизация на основе состояния пользователя»Маршрутизируйте в зависимости от состояния пользователя:
use HybridGram\Core\Routing\Attributes\FromUserState;use HybridGram\Core\Routing\Attributes\ToUserState;
#[OnTextMessage]#[FromUserState('waiting_name')]#[ToUserState('name_received')]public function handleNameInput(TextMessageData $data): void { // Обрабатывает только если пользователь в состоянии 'waiting_name' // Переходит в состояние 'name_received' после выполнения}Состояние чата
Заголовок раздела «Состояние чата»Маршрутизируйте на основе состояния чата:
use HybridGram\Core\Routing\Attributes\FromChatState;use HybridGram\Core\Routing\Attributes\ToChatState;
#[OnTextMessage]#[FromChatState('setup_mode')]public function handleSetup(TextMessageData $data): void { // Только когда чат в режиме 'setup_mode'}Комбинирование атрибутов
Заголовок раздела «Комбинирование атрибутов»Вы можете комбинировать несколько атрибутов на одном методе:
#[OnTextMessage(pattern: 'price:*')]#[ForBot('main')]#[ChatTypes([ChatType::PRIVATE])]#[FromUserState('shopping')]public function handlePriceQuery(TextMessageData $data): void { // Этот обработчик срабатывает только когда ВСЕ условия выполнены: // - Текст сообщения содержит шаблон 'price:*' // - Бот 'main' // - Чат приватный // - Пользователь в состоянии 'shopping'}Лучшие практики
Заголовок раздела «Лучшие практики»Организация
Заголовок раздела «Организация»Группируйте связанные обработчики в выделённых классах контроллера:
<?php
namespace App\Telegram\Handlers;
class CommandHandler{ #[OnCommand('/start')] public function handleStart(CommandData $data): void {}
#[OnCommand('/help')] public function handleHelp(CommandData $data): void {}}
class MessageHandler{ #[OnTextMessage] public function handleMessage(TextMessageData $data): void {}}Доступные пути
Заголовок раздела «Доступные пути»Убедитесь, что ваши классы обработчиков находятся в доступных местоположениях. По умолчанию фреймворк сканирует:
app/Telegram/app/Handlers/
Если нужно, сконфигурируйте дополнительные пути.
Безопасность типов
Заголовок раздела «Безопасность типов»Всегда добавляйте тип параметру данных:
// ✅ Хорошо - типы предотвращают ошибки#[OnCommand('/start')]public function handleStart(CommandData $data): void {}
// ❌ Избегайте - теряется безопасность типов#[OnCommand('/start')]public function handleStart($data): void {}Сравнение с фасадной маршрутизацией
Заголовок раздела «Сравнение с фасадной маршрутизацией»Маршрутизация через фасад (традиционный способ)
Заголовок раздела «Маршрутизация через фасад (традиционный способ)»TelegramRouter::onCommand('/start', function(CommandData $data) { // ...});
TelegramRouter::onTextMessage(function(TextMessageData $data) { // ...});Маршрутизация через атрибуты (современный способ)
Заголовок раздела «Маршрутизация через атрибуты (современный способ)»class BotHandler{ #[OnCommand('/start')] public function handleStart(CommandData $data): void { // ... }
#[OnTextMessage] public function handleMessage(TextMessageData $data): void { // ... }}Оба подхода работают одинаково хорошо. Выбирайте в зависимости от предпочтений вашего проекта:
- Атрибуты: Лучше для больших проектов с множеством обработчиков
- Фасад: Лучше для небольших проектов или когда все маршруты в одном месте
Продвинутые темы
Заголовок раздела «Продвинутые темы»Пользовательские атрибуты
Заголовок раздела «Пользовательские атрибуты»Вы можете создавать пользовательские атрибуты, расширяющие TelegramRouteAttribute:
use HybridGram\Core\Routing\Attributes\TelegramRouteAttribute;use HybridGram\Core\Routing\TelegramRouteBuilder;
#[Attribute(Attribute::TARGET_METHOD)]final class OnVIP implements TelegramRouteAttribute{ public function registerRoute(TelegramRouteBuilder $builder, \Closure|string|array $action): void { // Пользовательская логика регистрации $builder->onTextMessage($action) ->middleware(VIPCheckMiddleware::class); }}Кеширование атрибутов
Заголовок раздела «Кеширование атрибутов»В production маршруты атрибутов кешируются для лучшей производительности. Запустите:
php artisan config:cacheЧтобы очистить кеш во время разработки, используйте:
php artisan config:clearСмотрите также
Заголовок раздела «Смотрите также»- Базовая маршрутизация — Обзор концепций маршрутизации
- Middleware — Использование middleware с маршрутами
- Состояния — Управление состояниями пользователя и чата