PHP项目Symfony Notifier通道

wen PHP项目 1

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

PHP项目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
  • 灵活路由 - 根据不同策略分配到不同通道
  • 可扩展性 - 轻松添加自定义通道
  • 失败处理 - 内置异常处理和降级机制
  • 调试友好 - 开发环境可禁用实际发送

选择合适的通道组合,可以构建强大且可靠的通知系统。

抱歉,评论功能暂时关闭!