PHPAPI短信发送怎么集成

wen PHP项目 8

本文目录导读:

PHPAPI短信发送怎么集成

  1. 基本集成步骤
  2. 具体服务商集成示例
  3. 验证码发送示例
  4. 最佳实践建议
  5. 注意事项

我将为您详细介绍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')
]);

注意事项

  1. API密钥安全:不要在前端暴露API密钥,使用环境变量或配置文件管理
  2. 短信签名:需要提前在服务商处申请并通过审核
  3. 发送频率:合理控制发送频率,避免被认定为垃圾短信
  4. 错误处理:实现完善的错误处理和重试机制
  5. 日志记录:记录所有短信发送的详细日志,便于问题追踪
  6. 成本控制:注意短信发送的成本,避免被恶意利用

选择短信服务商时,建议对比各家服务的稳定性、价格和API易用性,选择最适合您项目需求的方案。

抱歉,评论功能暂时关闭!