菜鸟-创作你的创作

PHP短信发送功能的实现与优化指南

下面给你一份 “PHP 短信发送功能的实现与优化指南”,适合用于你的网站项目或 API 后端,包含完整架构、代码示例、优化策略与常见问题排查。


📱 PHP 短信发送功能的实现与优化指南

(适用于验证码短信、通知短信、营销短信)


1. 📌 短信发送整体架构

大多数 PHP 项目会采用下图的架构:

Your PHP App  →  SMS Service Layer  →  SMS Provider API (阿里云/腾讯云/容联云/国内短信平台)

核心包含 3 步:

  1. 创建 SMS 服务类(发送、日志、限流)
  2. 调用第三方短信服务商 API
  3. 处理返回值 + 存储发送记录 + 做限流

2. 🚀 第一步:选择短信服务商

常见高可用短信网关:

服务商特点适用场景
阿里云短信稳定、国内最常用、价格适中网站验证码、通知
腾讯云短信稳定性强、API 简单小程序、公众号、电商
容联云通讯支持语音验证码呼叫中心类
Twilio(海外)国际短信海外业务

建议:国内用阿里云;国际用 Twilio。


3. 🧩 第二步:创建一个通用短信发送类(PHP)

下面以阿里云为例(最常用):

📌 SmsService.php

<?php
class SmsService
{
    private $accessKeyId;
    private $accessKeySecret;
    private $signName;

    public function __construct($accessKeyId, $accessKeySecret, $signName)
    {
        $this->accessKeyId = $accessKeyId;
        $this->accessKeySecret = $accessKeySecret;
        $this->signName = $signName;
    }

    public function send($phoneNumber, $templateCode, $templateParams = [])
    {
        $params = [
            "PhoneNumbers" => $phoneNumber,
            "SignName" => $this->signName,
            "TemplateCode" => $templateCode,
            "TemplateParam" => json_encode($templateParams, JSON_UNESCAPED_UNICODE)
        ];

        $content = $this->request("dysmsapi.aliyuncs.com", $params);
        return json_decode($content, true);
    }

    private function request($domain, $params)
    {
        $apiParams = array_merge([
            "RegionId" => "cn-hangzhou",
            "Action" => "SendSms",
            "Version" => "2017-05-25"
        ], $params);

        $url = "https://{$domain}/?";

        return file_get_contents($url . http_build_query($apiParams));
    }
}


4. 🎯 第三步:调用示例(如发送验证码)

$sms = new SmsService("yourKeyId", "yourSecret", "签名名称");

$response = $sms->send(
    "13888888888",
    "SMS_12345678",
    ["code" => rand(100000, 999999)]
);

print_r($response);


5. 🔐 第四步:加入验证码缓存(Redis)

验证码必须加 时间限制 & 限流

5.1 保存验证码

$redis->setex("sms:code:$phone", 300, $code); // 5分钟

5.2 限制每个手机号 60 秒发送一次

if ($redis->exists("sms:limit:$phone")) {
    return "发送太频繁,请稍后再试";
}
$redis->setex("sms:limit:$phone", 60, 1);


6. ⚙️ 优化策略(必须做)

6.1 ✨ 幂等性:防止短时间重复发送

使用 Redis 控制:

一手机号 60 秒只能发送一次  
同一 IP 1 小时最多 20 条


6.2 ✨ 短信发送记录

表结构(MySQL):

CREATE TABLE sms_log (
    id INT AUTO_INCREMENT PRIMARY KEY,
    phone VARCHAR(20),
    template VARCHAR(50),
    params VARCHAR(255),
    status TINYINT COMMENT '0=失败 1=成功',
    response TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);


6.3 ✨ 自动切换短信服务商(可选)

防止某一平台故障,可以做:

try {
    $response = $aliyun->send(...);
} catch (Exception $e) {
    $response = $tencent->send(...); // fallback
}


7. 🛠️ 常见错误排查与解决

错误提示原因解决方案
InvalidSignName签名未审核通过去短信平台审核
TemplateCode error模板未审核提交审核
PhoneNumber illegal手机号格式错用正则校正
RequestLimitExceeded超出频率添加 Redis 限流
触发黑名单同一手机号发送过多控制发送次数

8. 🔒 推荐添加的安全保护


9. 📦 开源可直接使用的 PHP 短信 SDK

服务商SDK
阿里云composer require alibabacloud/client
腾讯云composer require tencentcloud/tencentcloud-sdk-php
Twiliocomposer require twilio/sdk
退出移动版