本文目录导读:

我将为您详细介绍PHP集成API短信发送的完整流程,这里以常见的短信服务商为例(如阿里云短信、腾讯云短信等)。
基本集成步骤
1 准备工作
// 1. 注册短信服务商账号 // 2. 获取API密钥(AccessKey/SecretKey) // 3. 申请短信签名和模板
2 通用发送函数
<?php
/**
* 短信发送通用函数
*/
class SmsService {
private $apiKey;
private $apiSecret;
private $signName; // 短信签名
public function __construct($apiKey, $apiSecret, $signName) {
$this->apiKey = $apiKey;
$this->apiSecret = $apiSecret;
$this->signName = $signName;
}
/**
* 发送短信
* @param string $phone 手机号码
* @param string $templateCode 模板代码
* @param array $params 模板参数
* @return bool
*/
public function send($phone, $templateCode, $params = []) {
// 具体实现取决于短信服务商
return $this->callApi($phone, $templateCode, $params);
}
}
具体服务商集成示例
1 阿里云短信集成
<?php
// 需要安装阿里云SDK: composer require alibabacloud/dysmsapi
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
class AliyunSmsService {
private $accessKeyId;
private $accessKeySecret;
private $signName;
public function __construct($accessKeyId, $accessKeySecret, $signName) {
$this->accessKeyId = $accessKeyId;
$this->accessKeySecret = $accessKeySecret;
$this->signName = $signName;
// 初始化客户端
AlibabaCloud::accessKeyClient($accessKeyId, $accessKeySecret)
->regionId('cn-hangzhou')
->asDefaultClient();
}
/**
* 发送短信
*/
public function sendSms($phone, $templateCode, $templateParam = []) {
try {
$result = AlibabaCloud::rpc()
->product('Dysmsapi')
->version('2017-05-25')
->action('SendSms')
->method('POST')
->host('dysmsapi.aliyuncs.com')
->options([
'query' => [
'RegionId' => 'cn-hangzhou',
'PhoneNumbers' => $phone,
'SignName' => $this->signName,
'TemplateCode' => $templateCode,
'TemplateParam' => json_encode($templateParam),
],
])
->request();
$response = $result->toArray();
if ($response['Code'] == 'OK') {
return [
'success' => true,
'message' => '发送成功',
'data' => $response
];
} else {
return [
'success' => false,
'message' => $response['Message'],
'code' => $response['Code']
];
}
} catch (ClientException $e) {
return [
'success' => false,
'message' => $e->getErrorMessage()
];
} catch (ServerException $e) {
return [
'success' => false,
'message' => $e->getErrorMessage()
];
}
}
}
// 使用示例
$sms = new AliyunSmsService('your_access_key_id', 'your_access_key_secret', '您的签名');
$result = $sms->sendSms('13800138000', 'SMS_123456789', ['code' => '123456']);
2 腾讯云短信集成
<?php
// 需要安装腾讯云SDK: composer require tencentcloud/tencentcloud-sdk-php
use TencentCloud\Common\Credential;
use TencentCloud\Common\Profile\ClientProfile;
use TencentCloud\Common\Profile\HttpProfile;
use TencentCloud\Sms\V20190711\SmsClient;
use TencentCloud\Sms\V20190711\Models\SendSmsRequest;
class TencentSmsService {
private $secretId;
private $secretKey;
private $appId;
private $signName;
public function __construct($secretId, $secretKey, $appId, $signName) {
$this->secretId = $secretId;
$this->secretKey = $secretKey;
$this->appId = $appId;
$this->signName = $signName;
}
/**
* 发送短信
*/
public function sendSms($phone, $templateId, $templateParams = []) {
try {
$cred = new Credential($this->secretId, $this->secretKey);
$httpProfile = new HttpProfile();
$httpProfile->setEndpoint('sms.tencentcloudapi.com');
$clientProfile = new ClientProfile();
$clientProfile->setHttpProfile($httpProfile);
$client = new SmsClient($cred, 'ap-guangzhou', $clientProfile);
$req = new SendSmsRequest();
$req->SmsSdkAppid = $this->appId;
$req->Sign = $this->signName;
$req->TemplateID = $templateId;
$req->PhoneNumberSet = ['+86' . $phone];
$req->TemplateParamSet = $templateParams;
$resp = $client->SendSms($req);
$result = json_decode($resp->toJsonString(), true);
if ($result['SendStatusSet'][0]['Code'] == 'Ok') {
return [
'success' => true,
'message' => '发送成功',
'data' => $result
];
} else {
return [
'success' => false,
'message' => $result['SendStatusSet'][0]['Message'],
'code' => $result['SendStatusSet'][0]['Code']
];
}
} catch (\Exception $e) {
return [
'success' => false,
'message' => $e->getMessage()
];
}
}
}
// 使用示例
$sms = new TencentSmsService('your_secret_id', 'your_secret_key', '1400xxxxxx', '您的签名');
$result = $sms->sendSms('13800138000', '123456', ['123456']);
3 简单HTTP请求方式(不依赖SDK)
<?php
class SimpleSmsService {
private $apiUrl;
private $apiKey;
public function sendSms($phone, $content) {
$postData = [
'api_key' => $this->apiKey,
'phone' => $phone,
'content' => $content
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->apiUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode == 200) {
return json_decode($response, true);
} else {
return false;
}
}
}
验证码发送示例
<?php
class VerificationCodeService {
private $smsService;
public function __construct($smsService) {
$this->smsService = $smsService;
}
/**
* 生成并发送验证码
*/
public function sendVerificationCode($phone) {
// 生成6位随机验证码
$code = str_pad(rand(0, 999999), 6, '0', STR_PAD_LEFT);
// 存储验证码到缓存(Redis/数据库)
$this->storeVerificationCode($phone, $code);
// 发送短信
$result = $this->smsService->sendSms(
$phone,
'SMS_VERIFICATION_TEMPLATE',
['code' => $code, 'minute' => 5]
);
return $result;
}
/**
* 验证验证码
*/
public function verifyCode($phone, $code) {
$storedCode = $this->getStoredVerificationCode($phone);
if ($storedCode && $storedCode == $code) {
// 验证成功后删除验证码
$this->deleteVerificationCode($phone);
return true;
}
return false;
}
private function storeVerificationCode($phone, $code) {
// 使用Redis存储,5分钟过期
// \Redis::setex('sms_code:' . $phone, 300, $code);
}
private function getStoredVerificationCode($phone) {
// return \Redis::get('sms_code:' . $phone);
}
private function deleteVerificationCode($phone) {
// \Redis::del('sms_code:' . $phone);
}
}
最佳实践建议
1 错误处理
class SmsException extends \Exception {
protected $errorCode;
public function __construct($message, $code = 0) {
parent::__construct($message, $code);
$this->errorCode = $code;
}
}
try {
$result = $smsService->sendSms($phone, $templateCode, $params);
if (!$result['success']) {
throw new SmsException($result['message'], $result['code']);
}
} catch (SmsException $e) {
// 记录日志
error_log("短信发送失败: " . $e->getMessage());
// 返回错误信息
return ['error' => $e->getMessage()];
}
2 频率限制
class SmsRateLimiter {
private $redis;
private $maxPerMinute = 1; // 每分钟最大发送次数
private $maxPerDay = 5; // 每天最大发送次数
public function canSend($phone) {
$minuteKey = "sms_limit:minute:{$phone}";
$dayKey = "sms_limit:day:" . date('Ymd') . ":{$phone}";
// 检查分钟限制
$minuteCount = $this->redis->get($minuteKey) ?: 0;
if ($minuteCount >= $this->maxPerMinute) {
return false;
}
// 检查天限制
$dayCount = $this->redis->get($dayKey) ?: 0;
if ($dayCount >= $this->maxPerDay) {
return false;
}
return true;
}
}
3 日志记录
// 使用Monolog记录日志
$log = new \Monolog\Logger('sms');
$log->pushHandler(new \Monolog\Handler\StreamHandler('path/to/sms.log', \Monolog\Logger::INFO));
$log->info('短信发送', [
'phone' => $phone,
'template' => $templateCode,
'result' => $result,
'time' => date('Y-m-d H:i:s')
]);
注意事项
- API密钥安全:不要在前端暴露API密钥,使用环境变量或配置文件管理
- 短信签名:需要提前在服务商处申请并通过审核
- 发送频率:合理控制发送频率,避免被认定为垃圾短信
- 错误处理:实现完善的错误处理和重试机制
- 日志记录:记录所有短信发送的详细日志,便于问题追踪
- 成本控制:注意短信发送的成本,避免被恶意利用
选择短信服务商时,建议对比各家服务的稳定性、价格和API易用性,选择最适合您项目需求的方案。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播