我来为您设计一个PHP统一通知接口,这是一个常见的需求,用于接收来自不同渠道(短信、邮件、App推送等)的通知。

统一通知接口设计方案
数据表结构
-- 通知数据表
CREATE TABLE `notifications` (
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`notification_id` VARCHAR(64) NOT NULL COMMENT '业务通知ID',
`channel` VARCHAR(20) NOT NULL COMMENT '渠道: sms,email,push',
`type` VARCHAR(50) NOT NULL COMMENT '通知类型', VARCHAR(200) DEFAULT NULL COMMENT '标题',
`content` TEXT NOT NULL COMMENT '内容',
`receiver` JSON NOT NULL COMMENT '接收者信息',
`data` JSON DEFAULT NULL COMMENT '扩展数据',
`status` TINYINT DEFAULT 0 COMMENT '状态: 0待发送,1已发送,2失败,3已读',
`send_result` JSON DEFAULT NULL COMMENT '发送结果',
`sent_at` DATETIME DEFAULT NULL COMMENT '发送时间',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_notification_id` (`notification_id`),
INDEX `idx_channel_status` (`channel`, `status`),
INDEX `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
统一通知接口
<?php
/**
* 统一通知接口
*
* @author Your Name
* @date 2024-01-01
*/
require_once 'database.php'; // 数据库连接
class UnifiedNotification {
private $db;
private $channels = [
'sms' => 'SmsChannel',
'email' => 'EmailChannel',
'push' => 'PushChannel',
'wechat' => 'WechatChannel'
];
public function __construct($db) {
$this->db = $db;
}
/**
* 统一发送通知接口
*
* @param array $params 通知参数
* @return array 发送结果
*/
public function send($params) {
try {
// 参数验证
$this->validateParams($params);
// 构建通知数据
$notification = [
'notification_id' => $this->generateNotificationId(),
'channel' => $params['channel'],
'type' => $params['type'],
'title' => $params['title'] ?? '',
'content' => $params['content'],
'receiver' => json_encode($params['receiver']),
'data' => json_encode($params['data'] ?? []),
'status' => 0
];
// 保存到数据库
$notificationId = $this->saveNotification($notification);
// 发送通知
$result = $this->dispatch($notification);
// 更新发送状态
$this->updateNotificationStatus($notificationId, $result);
return [
'code' => 200,
'message' => '通知发送成功',
'data' => [
'notification_id' => $notification['notification_id'],
'channel' => $params['channel'],
'status' => $result['status'],
'send_result' => $result
]
];
} catch (Exception $e) {
return [
'code' => 400,
'message' => $e->getMessage(),
'data' => null
];
}
}
/**
* 批量发送通知
*/
public function sendBatch($params) {
$results = [];
foreach ($params['notifications'] as $notification) {
$results[] = $this->send($notification);
}
return [
'code' => 200,
'message' => '批量发送完成',
'data' => $results
];
}
/**
* 验证参数
*/
private function validateParams($params) {
// 必填参数检查
$required = ['channel', 'type', 'content', 'receiver'];
foreach ($required as $field) {
if (empty($params[$field])) {
throw new Exception("参数 {$field} 不能为空");
}
}
// 渠道检查
if (!isset($this->channels[$params['channel']])) {
throw new Exception("不支持的渠道: {$params['channel']}");
}
// 接收者检查
if (!is_array($params['receiver']) || empty($params['receiver'])) {
throw new Exception("接收者信息不能为空");
}
}
/**
* 生成通知ID
*/
private function generateNotificationId() {
return date('YmdHis') . str_pad(mt_rand(1, 999999), 6, '0', STR_PAD_LEFT);
}
/**
* 保存通知到数据库
*/
private function saveNotification($data) {
$sql = "INSERT INTO notifications (notification_id, channel, type, title, content, receiver, data, status)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = $this->db->prepare($sql);
$stmt->execute([
$data['notification_id'],
$data['channel'],
$data['type'],
$data['title'],
$data['content'],
$data['receiver'],
$data['data'],
$data['status']
]);
return $this->db->lastInsertId();
}
/**
* 分发到具体渠道
*/
private function dispatch($notification) {
$channelClass = $this->channels[$notification['channel']];
if (!class_exists($channelClass)) {
throw new Exception("渠道类不存在: {$channelClass}");
}
$channel = new $channelClass();
// 构建渠道数据
$channelData = [
'notification_id' => $notification['notification_id'],
'title' => $notification['title'],
'content' => $notification['content'],
'receiver' => json_decode($notification['receiver'], true),
'data' => json_decode($notification['data'], true)
];
return $channel->send($channelData);
}
/**
* 更新通知状态
*/
private function updateNotificationStatus($id, $result) {
$status = $result['status'] === 'success' ? 1 : 2;
$sql = "UPDATE notifications SET status = ?, send_result = ?, sent_at = NOW() WHERE id = ?";
$stmt = $this->db->prepare($sql);
$stmt->execute([
$status,
json_encode($result),
$id
]);
}
/**
* 查询通知状态
*/
public function query($notificationId) {
$sql = "SELECT * FROM notifications WHERE notification_id = ?";
$stmt = $this->db->prepare($sql);
$stmt->execute([$notificationId]);
$data = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$data) {
return [
'code' => 404,
'message' => '通知不存在',
'data' => null
];
}
$data['receiver'] = json_decode($data['receiver'], true);
$data['data'] = json_decode($data['data'], true);
$data['send_result'] = json_decode($data['send_result'], true);
return [
'code' => 200,
'message' => '查询成功',
'data' => $data
];
}
}
渠道实现类
<?php
/**
* 短信渠道
*/
class SmsChannel {
public function send($data) {
// 实现短信发送逻辑
// 例如使用阿里云短信服务
try {
// 模拟发送
$result = [
'status' => 'success',
'message' => '短信发送成功',
'message_id' => 'MSG' . time(),
'channel' => 'sms'
];
// 实际调用短信SDK
// $smsService = new AliyunSms();
// $result = $smsService->send($data);
return $result;
} catch (Exception $e) {
return [
'status' => 'failed',
'message' => $e->getMessage(),
'channel' => 'sms'
];
}
}
}
/**
* 邮件渠道
*/
class EmailChannel {
public function send($data) {
// 实现邮件发送逻辑
try {
// 模拟发送
$result = [
'status' => 'success',
'message' => '邮件发送成功',
'message_id' => 'EMAIL' . time(),
'channel' => 'email'
];
// 实际发送邮件代码
// $mailer = new Mailer();
// $result = $mailer->send($data);
return $result;
} catch (Exception $e) {
return [
'status' => 'failed',
'message' => $e->getMessage(),
'channel' => 'email'
];
}
}
}
/**
* 推送渠道
*/
class PushChannel {
public function send($data) {
// 实现推送逻辑
try {
$result = [
'status' => 'success',
'message' => '推送成功',
'message_id' => 'PUSH' . time(),
'channel' => 'push'
];
// 实际推送代码
// $pushService = new PushService();
// $result = $pushService->send($data);
return $result;
} catch (Exception $e) {
return [
'status' => 'failed',
'message' => $e->getMessage(),
'channel' => 'push'
];
}
}
}
HTTP接口调用示例
<?php
/**
* 统一通知接口入口文件
* api/notify.php
*/
// 设置响应头
header('Content-Type: application/json; charset=utf-8');
// 接收请求
$method = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];
// 解析路由
$path = parse_url($uri, PHP_URL_PATH);
$action = basename($path);
require_once 'UnifiedNotification.php';
require_once 'SmsChannel.php';
require_once 'EmailChannel.php';
require_once 'PushChannel.php';
$db = getDatabaseConnection();
$notificationService = new UnifiedNotification($db);
switch ($method) {
case 'POST':
// 发送通知
$params = json_decode(file_get_contents('php://input'), true);
if ($action === 'batch') {
$result = $notificationService->sendBatch($params);
} else {
$result = $notificationService->send($params);
}
break;
case 'GET':
// 查询通知
$notificationId = $_GET['id'] ?? '';
$result = $notificationService->query($notificationId);
break;
default:
$result = [
'code' => 405,
'message' => '不支持的请求方法',
'data' => null
];
}
echo json_encode($result, JSON_UNESCAPED_UNICODE);
调用示例
// 发送短信通知
$params = [
'channel' => 'sms',
'type' => 'verify_code', => '验证码',
'content' => '您的验证码是:123456,5分钟内有效。',
'receiver' => [
'mobile' => '13800138000'
],
'data' => [
'template_id' => 'SMS_001',
'code' => '123456'
]
];
// 发送邮件通知
$emailParams = [
'channel' => 'email',
'type' => 'order_confirmation', => '订单确认',
'content' => '您的订单已确认,订单号:12345',
'receiver' => [
'email' => 'user@example.com'
],
'data' => [
'order_id' => '12345'
]
];
配置文件
<?php
// config/notification.php
return [
// 渠道配置
'channels' => [
'sms' => [
'driver' => 'aliyun',
'access_key' => 'your_access_key',
'secret_key' => 'your_secret_key',
'sign_name' => '你的签名',
'endpoint' => 'https://dysmsapi.aliyuncs.com'
],
'email' => [
'host' => 'smtp.example.com',
'port' => 465,
'username' => 'user@example.com',
'password' => 'your_password'
],
'push' => [
'app_key' => 'your_app_key',
'master_secret' => 'your_master_secret'
]
],
// 重试配置
'retry' => [
'max_attempts' => 3,
'delay_seconds' => 60
],
// 日志配置
'logging' => [
'enabled' => true,
'path' => '/path/to/notification.log'
]
];
这个统一通知接口设计具有以下特点:
- 统一入口:所有通知都通过同一个接口发送
- 多渠道支持:支持短信、邮件、推送等多种渠道
- 异步处理:可以扩展为队列异步处理
- 状态追踪:记录每条通知的发送状态
- 可扩展性:方便添加新的渠道
- 错误处理:完善的异常处理机制
您可以根据实际需求调整渠道实现和配置。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播