我将为您详细介绍Symfony Notifier通道的各个方面。

Symfony Notifier 通道概述
什么是Notifier通道?
Symfony Notifier通道是用于发送通知的不同通信渠道,每个通道对应一种通知发送方式(如邮件、短信、聊天消息等)。
核心组件
Symfony Notifier 核心概念:
┌──────────────────────────────────────────┐
│ Notifier │
├──────────────────────────────────────────┤
│ Channel 1: Email │ Channel 2: SMS│
│ Channel 3: Chat │ Channel 4: Push│
│ Channel 5: Voice │ Channel 6: ...│
└──────────────────────────────────────────┘
安装
composer require symfony/notifier
配置通道
基本配置 (config/packages/notifier.yaml):
framework:
notifier:
enabled: true
# 默认通道
default_channel: 'email'
# 通道配置
texter_transports:
main: '%env(TEXTER_DSN)%'
chatter_transports:
slack: '%env(SLACK_DSN)%'
channel_policy:
urgent: ['email', 'sms']
high: ['email']
medium: ['email']
常用通道类型
邮件通道 (Email)
# .env MAILER_DSN=smtp://user:pass@smtp.example.com:25
use Symfony\Component\Notifier\Message\EmailMessage;
use Symfony\Component\Mime\Email;
$email = (new Email())
->from('no-reply@example.com')
->to('user@example.com')
->subject('通知主题')
->html('<p>通知内容</p>');
$notification = new EmailMessage($email);
$notifier->send($notification);
短信通道 (SMS)
# 使用Twilio TEXTER_DSN=twilio://SID:TOKEN@default?from=+1234567890 # 使用Vonage(原Nexmo) TEXTER_DSN=vonage://KEY:SECRET@default?from=1234567890
use Symfony\Component\Notifier\Message\SmsMessage;
$sms = new SmsMessage(
'+8613800138000', // 收件人
'您的验证码是: 123456' // 内容
);
$notifier->send($sms);
聊天通道 (Chat)
# Slack CHATTER_DSN=slack://TOKEN@default?channel=general # Discord CHATTER_DSN=discord://WEBHOOK_ID:TOKEN@default # Telegram CHATTER_DSN=telegram://TOKEN@default?channel=@channelname
use Symfony\Component\Notifier\Message\ChatMessage;
$chat = new ChatMessage('系统通知:新用户注册');
$notifier->send($chat, ['slack']);
创建自定义通道
// src/Notifier/WeChatChannel.php
namespace App\Notifier;
use Symfony\Component\Notifier\Channel\ChannelInterface;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Recipient\Recipient;
class WeChatChannel implements ChannelInterface
{
private $wechatClient;
public function __construct(WeChatClient $wechatClient)
{
$this->wechatClient = $wechatClient;
}
public function supports(Notification $notification, Recipient $recipient): bool
{
return $recipient instanceof WeChatRecipient;
}
public function notify(Notification $notification, Recipient $recipient, ?string $transportName = null): void
{
$this->wechatClient->send(
$recipient->getWeChatId(),
$notification->getContent()
);
}
}
// 自定义收件人类
class WeChatRecipient implements RecipientInterface
{
private $weChatId;
public function __construct(string $weChatId)
{
$this->weChatId = $weChatId;
}
public function getWeChatId(): string
{
return $this->weChatId;
}
}
策略与路由
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\NotifierInterface;
class UserNotifier
{
private $notifier;
public function __construct(NotifierInterface $notifier)
{
$this->notifier = $notifier;
}
public function sendWelcomeNotification(User $user): void
{
$notification = (new Notification('欢迎加入!', ['email']))
->content('感谢您注册我们的平台')
->importance(Notification::IMPORTANCE_HIGH);
// 自动路由到正确通道
$this->notifier->send($notification, $user);
}
}
多通道发送
// 发送到多个通道
$notification = new Notification('系统通知', ['email', 'sms', 'slack']);
$notification->content('重要系统更新');
$notification->importance(Notification::IMPORTANCE_URGENT);
// 发送
$this->notifier->send($notification, $recipient);
// 检查发送结果
$sentCount = $this->notifier->send($notification, $recipient);
echo "已成功发送到 {$sentCount} 个通道";
事件和日志
# config/packages/notifier.yaml
framework:
notifier:
message_bus: true # 启用消息总线
logger: true # 启用日志
// 监听通知事件
use Symfony\Component\Notifier\Event\MessageEvent;
#[AsEventListener]
public function onMessage(MessageEvent $event): void
{
$message = $event->getMessage();
// 记录日志或修改消息
$event->setMessage($message);
}
生产环境最佳实践
# config/packages/notifier.yaml
framework:
notifier:
# 生产环境配置
when@prod:
texter_transports:
main: '%env(TEXTER_DSN)%'
chatter_transports:
slack: '%env(SLACK_DSN)%'
# 开发环境配置
when@dev:
texter_transports:
main: 'null://null' # 不实际发送
chatter_transports:
slack: 'null://null'
故障处理
use Symfony\Component\Notifier\Exception\TransportExceptionInterface;
try {
$this->notifier->send($notification, $recipient);
} catch (TransportExceptionInterface $e) {
// 通道发送失败处理
$this->logger->error('通知发送失败', [
'error' => $e->getMessage(),
'channel' => $e->getTransport()
]);
// 降级到其他通道
$this->fallbackNotifier->send($notification, $recipient);
}
完整示例
// src/Service/NotificationService.php
namespace App\Service;
use Symfony\Component\Notifier\NotifierInterface;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Recipient\Recipient;
class NotificationService
{
private $notifier;
public function __construct(NotifierInterface $notifier)
{
$this->notifier = $notifier;
}
public function sendOrderConfirmation(Order $order): void
{
$notification = new Notification('订单确认', ['email', 'sms']);
$notification->content(sprintf(
'您的订单 #%s 已确认,总金额: ¥%s',
$order->getId(),
$order->getTotal()
));
$notification->importance(Notification::IMPORTANCE_MEDIUM);
$recipient = new Recipient(
$order->getCustomerEmail(),
$order->getCustomerPhone()
);
$this->notifier->send($notification, $recipient);
}
}
Symfony Notifier通道提供了:
- 统一接口 - 所有通知使用相同API
- 灵活路由 - 根据不同策略分配到不同通道
- 可扩展性 - 轻松添加自定义通道
- 失败处理 - 内置异常处理和降级机制
- 调试友好 - 开发环境可禁用实际发送
选择合适的通道组合,可以构建强大且可靠的通知系统。