symfony发短信需通过notifier组件配置网关、路由和异步处理:①安装对应包(如aliyun-notifier)并配置notifier.yaml及环境变量;②notification类动态返回['sms']通道;③recipient实现getphone();④启用messenger异步发送防阻塞。

Symfony 发短信不是直接调 API,而是通过 Notifier 组件 走标准化通道。核心是配好短信网关、写对通知逻辑、确保渠道能被正确路由——发不出去,90% 是配置或路由问题,不是代码写错。
装包 + 配网关(国内常用阿里云/腾讯云)
官方不内置国内短信服务商,需手动引入对应包:
- 阿里云:运行
composer require symfony/aliyun-notifier - 腾讯云:运行
composer require symfony/tencentcloud-notifier - 互亿无线等第三方,需自定义 Transport(基于 HTTP 客户端封装)
然后在 config/packages/notifier.yaml 中启用 SMS 通道:
transports:
sms: 'aliyun://?region=cn-hangzhou'
同时确保环境变量齐全,例如阿里云需设置:
ALIYUN_ACCESS_KEY_ID=your_key_id ALIYUN_ACCESS_KEY_SECRET=your_key_secret ALIYUN_SMS_SIGN_NAME=【你的签名】 ALIYUN_SMS_TEMPLATE_CODE=SMS_123456789
变量名必须与文档严格一致,拼错一个字母就静默失败。
写 Notification 类(动态选渠道)
不要硬编码 ['sms'],而是让 getChannels() 根据接收者状态返回:
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Recipient\RecipientInterface;
class VerifyCodeNotification extends Notification
{
public function __construct(private string $code) { }
public function getChannels(RecipientInterface $recipient): array
{
return $recipient->getPhone() ? ['sms'] : [];
}
public function getContent(): string
{
return "您的验证码是:{$this->code}。请勿泄露给他人。";
}
}
这样既支持用户没填手机号时自动跳过,也避免邮件通道误触发。
Recipient 必须实现 getPhone()
Notifier 会自动调用 $recipient->getPhone() 获取号码,所以接收者类不能是数组或字符串:
use Symfony\Component\Notifier\Recipient\RecipientInterface;
class User implements RecipientInterface
{
public function __construct(private string $phone) {}
public function getPhone(): ?string
{
return $this->phone;
}
public function getEmail(): ?string
{
return null;
}
}
发送时传入该实例即可:
$notifier->send(
new VerifyCodeNotification('6789'),
new User('+8613800138000')
);
发之前先确认是否异步
默认同步发送,短信网关响应慢会导致请求卡住。建议启用 Messenger 异步处理:
- 安装
symfony/messenger - 在
notifier.yaml中设置:chatter_transports: ['async'] - 或直接用
$notifier->send($notification, $recipient, ['async'])
异步后,Notifier 会把消息丢进 Messenger 队列,由 worker 后台执行,主流程不阻塞。











