本文目录导读:

在PHP项目中实现短信推送,通常是通过调用第三方短信服务提供商(SMS Provider)的API来完成的,你不需要自己搭建短信网关(成本高、不稳定),而是使用阿里云、腾讯云、七牛云、Twilio(国外)等成熟服务。
以下是实现短信推送的标准流程和代码示例。
核心步骤概览
- 选择服务商:阿里云短信、腾讯云短信、Twilio、Submail等。
- 注册并获取密钥:获取
AccessKeyID、AccessKeySecret(或AppID、AppKey)。 - 申请短信模板需在服务商后台审核通过(如“您的验证码是:${code}”)。
- 安装SDK或使用HTTP请求:通过Composer安装官方SDK,或直接Curl调用API。
- 编写发送逻辑:调用SDK方法,传入手机号、模板参数等。
- 处理返回结果:记录日志、处理发送失败情况。
使用阿里云短信(国内主流)
阿里云是国内最常用的短信服务商之一,稳定性高。
安装SDK
在项目根目录运行Composer:
composer require alibabacloud/dysmsapi-20170525 2.0.24
PHP发送短信代码
<?php
require_once 'vendor/autoload.php';
use AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi;
use AlibabaCloud\OpenApiUtil\OpenApiUtilClient;
use AlibabaCloud\Tea\Exception\TeaException;
use AlibabaCloud\Tea\Utils\Utils;
class SmsService
{
private $accessKeyId;
private $accessKeySecret;
private $signName; // 短信签名,如 “某某科技”
private $templateCode; // 模板CODE,如 “SMS_123456789”
public function __construct()
{
$this->accessKeyId = '你的AccessKeyId';
$this->accessKeySecret = '你的AccessKeySecret';
$this->signName = '你的签名';
$this->templateCode = '你的模板CODE';
}
/**
* 发送短信
* @param string $phone 手机号
* @param array $params 模板参数,如 ['code'=>'123456']
* @return bool
*/
public function sendSms(string $phone, array $params): bool
{
// 1. 创建客户端
$client = self::createClient($this->accessKeyId, $this->accessKeySecret);
// 2. 构造请求
$sendSmsRequest = new \AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendSmsRequest([
'phoneNumbers' => $phone,
'signName' => $this->signName,
'templateCode' => $this->templateCode,
'templateParam' => json_encode($params) // 必须转为JSON字符串
]);
try {
// 3. 发送并获取响应
$response = $client->sendSms($sendSmsRequest);
// 4. 判断是否成功(阿里云返回Code为OK表示成功)
if ($response->body->code === 'OK') {
// 记录成功日志
file_put_contents('sms.log', date('Y-m-d H:i:s') . " 发送成功: $phone | BizId: " . $response->body->bizId . PHP_EOL, FILE_APPEND);
return true;
} else {
// 记录失败原因
file_put_contents('sms.log', date('Y-m-d H:i:s') . " 发送失败: $phone | Code: " . $response->body->code . " | Message: " . $response->body->message . PHP_EOL, FILE_APPEND);
return false;
}
} catch (TeaException $e) {
// 打印错误信息(生产环境建议记录日志)
echo $e->getMessage() . PHP_EOL;
return false;
} catch (\Exception $e) {
echo $e->getMessage() . PHP_EOL;
return false;
}
}
/**
* 创建客户端实例
*/
private static function createClient($accessKeyId, $accessKeySecret)
{
$config = new \AlibabaCloud\Tea\Config([
'accessKeyId' => $accessKeyId,
'accessKeySecret' => $accessKeySecret
]);
// 短信API默认接入点
$config->endpoint = 'dysmsapi.aliyuncs.com';
return new Dysmsapi($config);
}
}
// 使用示例
$sms = new SmsService();
$result = $sms->sendSms('13800138000', ['code' => '9527']);
if ($result) {
echo "短信发送成功";
} else {
echo "短信发送失败,请查看日志";
}
?>
使用腾讯云短信
腾讯云也是常见选择,API调用方式类似。
安装SDK
composer require tencentcloud/sms-v20210111
发送代码(精简版)
<?php
require_once 'vendor/autoload.php';
use TencentCloud\Sms\V20210111\SmsClient;
use TencentCloud\Sms\V20210111\Models\SendSmsRequest;
use TencentCloud\Common\Exception\TencentCloudSDKException;
use TencentCloud\Common\Credential;
class TencentSms
{
private $secretId;
private $secretKey;
private $appId; // 短信应用ID: 1400开头
private $signName; // 短信签名
private $templateId; // 模板ID
public function __construct()
{
$this->secretId = '你的SecretId';
$this->secretKey = '你的SecretKey';
$this->appId = '1400XXXXXX';
$this->signName = '你的签名';
$this->templateId = '1234567';
}
public function send($phone, $code)
{
try {
$cred = new Credential($this->secretId, $this->secretKey);
$client = new SmsClient($cred, "ap-guangzhou"); // 区域一般选广州
$req = new SendSmsRequest();
$req->PhoneNumberSet = ["+86" . $phone]; // 国际号需加前缀
$req->SmsSdkAppId = $this->appId;
$req->SignName = $this->signName;
$req->TemplateId = $this->templateId;
$req->TemplateParamSet = [$code]; // 模板参数,如 ['验证码']
$resp = $client->SendSms($req);
// 判断返回状态
$sendStatus = $resp->SendStatusSet[0];
if ($sendStatus->Code === 'Ok') {
return true;
} else {
// 记录失败信息
error_log("腾讯云短信发送失败: " . $sendStatus->Code . " - " . $sendStatus->Message);
return false;
}
} catch (TencentCloudSDKException $e) {
error_log("腾讯云SDK异常: " . $e->getMessage());
return false;
}
}
}
使用Twilio(国际短信/海外用户)
如果你的项目面向海外用户,Twilio是首选。
安装SDK
composer require twilio/sdk
发送代码
<?php
require_once 'vendor/autoload.php';
use Twilio\Rest\Client;
class TwilioSms
{
private $accountSid; // Twilio Account SID
private $authToken; // Twilio Auth Token
private $fromNumber; // Twilio购买的号码
public function __construct()
{
$this->accountSid = '你的ACCOUNT_SID';
$this->authToken = '你的AUTH_TOKEN';
$this->fromNumber = '+1234567890'; // 你拥有的Twilio号码
}
public function send($phone, $message)
{
$client = new Client($this->accountSid, $this->authToken);
try {
$message = $client->messages->create(
$phone, // 接收号码,如 '+8613800138000'
[
'from' => $this->fromNumber,
'body' => $message
]
);
if ($message->sid) {
return true; // 发送成功
}
return false;
} catch (\Exception $e) {
error_log("Twilio发送失败: " . $e->getMessage());
return false;
}
}
}
重要注意事项
- 密钥安全:
accessKeySecret等密钥绝不能写在代码中,应存入.env文件或配置中心,通过$_ENV或配置文件读取。 - 短信模板:所有服务商必须使用审核通过的模板,不能直接拼接任意内容发送(尤其是国内服务商,违反规定会被封禁)。
- 频率限制:避免对同一个手机号频繁发送(如1分钟内发5次以上),代码中应加入逻辑:
- 记录上次发送时间。
- 使用缓存(Redis/Memcached)设置发送间隔。
- 限制每天发送次数。
- 异常处理:网络超时、API限流、余额不足等情况需捕获并记录日志。
- 发送验证码:通常是先发送,然后服务器存储验证码(加过期时间),用户提交表单时比对。
- 并发处理:如果你的项目需要大量并发发送(如营销),建议使用消息队列(RabbitMQ、Redis队列)异步处理,而不是直接在请求中同步调用。
简单封装为通用函数示例
/**
* 发送验证码
* @param string $phone
* @param string $code
* @return bool
*/
function sendVerificationCode(string $phone, string $code): bool
{
// 1. 检查发送频率(伪代码)
if (isTooFrequent($phone)) {
return false; // 发送太频繁
}
// 2. 调用服务商
$sms = new SmsService; // 以阿里云为例
$result = $sms->sendSms($phone, ['code' => $code]);
// 3. 记录发送状态
if ($result) {
// 将验证码存入Redis,5分钟过期
// redis_set('sms_code:' . $phone, $code, 300);
// 记录发送时间
// redis_set('sms_last_send:' . $phone, time(), 60);
}
return $result;
}
选择一种你常用的服务商,按照上述代码进行修改,替换你的密钥和模板参数,即可在你的PHP项目中实现短信推送。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播