- 使用composer安装所需要的短信SDK。
阿里云短信SDK
$ composer require alibabacloud/sdk
腾讯云短信SDK
$ composer require tencentcloud/tencentcloud-sdk-php
- 目录结构
project
|-- app
|--common
|--lib
| |--sms
| | |--AilSms.php
| | |--TenSms.php
| | |--SmsBase.php
| `--ClassArr.php
`--business
|--api
|--SmsBusinee.php
- SmsBase为短信统一接口,所有短信使用都使用该接口,达到统一约束。
<?php
/**
* PHP version 7.1
*
* @date 2021-12-17 16:01:54
* @author xiangyang <827544120@qq.com>
*/
/**
* End file SmsBase.php
*/
declare(strict_types=1);
namespace app\common\lib\sms;
interface SmsBase
{
/**
*
* 短信统一接口
* @method SmsSend
* @param string $phone 接收手机号
* @param array $code 短信内容
* @param string $templateCode 短息模板ID
* @param string $signName 短信签名
*
* @return mixed
*
* @author xiangyang <827544120@qq.com>
*/
public static function SmsSend(string $phone, array $code, string $templateCode, string $signName);
}
- AliSms阿里云短信SDK调用方式。
<?php
/**
* PHP version 7.1
*
* @date 2021-12-16 15:10:03
* @author xiangyang <827544120@qq.com>
*/
/**
* End file Alisms.php
*/
declare(strict_types=1);
namespace app\common\lib\sms;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use think\facade\Log;
class AliSms implements SmsBase
{
/**
*
* 阿里云短信发送板块
* @method LoginSmsSend
* @param string $phone 发送手机号
* @param array $code 短信内容
* @param string $templateCode 短信模板ID
* @param string $signName 短信签名
*
* @return bool
* @throws ClientException
*
* @author xiangyang <827544120@qq.com>
*/
public static function SmsSend(string $phone, array $code,string $templateCode,
string $signName): bool
{
AlibabaCloud::accessKeyClient("填入ACCESSKEYID","填入ACCESSKEYSECRET")->regionId('cn-shanghai')->asDefaultClient();
try {
$result = AlibabaCloud::rpc()
->product('Dysmsapi')
->version('2017-05-25')
->action('SendSms')
->method('POST')
->host('dysmsapi.aliyuncs.com')
->options([
'query' => [
'PhoneNumbers' => $phone,
'SignName' => $signName,
'TemplateCode' => $templateCode,
'TemplateParam' => json_encode($code),
],
])
->request();
$result = $result->toArray();
//发送成功后并将阿里云返回写入日志
if (isset($result["Code"]) && $result["Code"] == "OK") {
Log::info("AliSms_LoginSmsSend_phone-{$phone}_Send_Success-" . json_encode($result));
return true;
}
//发送失败将阿里云返回写入日志
Log::info("AliSms_LoginSmsSend_phone-{$phone}_Send_Exception-".json_encode($result));
//将各种异常写入日志
} catch (ClientException $e) {
Log::error("AliSms_LoginSmsSend_phone-{$phone}_Send_Exception-" . $e->getMessage());
} catch (ServerException $e) {
Log::error("AliSms_LoginSmsSend_phone-{$phone}_Send_Exception-" . $e->getMessage());
}
return false;
}
}
- TenSms腾讯云短信SDK调用方法。
<?php
/**
* PHP version 7.1
*
* @date 2022-01-18 11:48:06
* @author xiangyang <827544120@qq.com>
*/
/**
* End file TenSms.php
*/
namespace app\common\lib\sms;
use TencentCloud\Common\Credential;
use TencentCloud\Common\Exception\TencentCloudSDKException;
use TencentCloud\Common\Profile\ClientProfile;
use TencentCloud\Common\Profile\HttpProfile;
use TencentCloud\Sms\V20210111\Models\SendSmsRequest;
use TencentCloud\Sms\V20210111\SmsClient;
use think\facade\Log;
class TenSms implements SmsBase
{
/**
*
* 腾讯云短信发送板块
* @method LoginSmsSend
*
* @param string $phone 发送手机号
* @param array $code 短信内容
* @param string $templateCode 短信模板ID
* @param string $signName 短信签名
*
* @return bool
*
* @author xiangyang <827544120@qq.com>
*/
public static function SmsSend(string $phone, array $codeDataArray, string $templateCode, string $signName)
{
try {
$cred = new Credential("填入SECRETID","填入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();
$phoneDataArray = array($phone);
$params = array(
"PhoneNumberSet" => $phoneDataArray,
"SmsSdkAppId" => "填入SDKAPPID",
"SignName" => $signName,
"TemplateId" => $templateCode,
"TemplateParamSet" => $codeDataArray,
);
$req->fromJsonString(json_encode($params));
$resp = $client->SendSms($req);
$result = json_decode(json_encode($resp),true);
//短信发送成功后将返回见过写入日志
if($result['SendStatusSet']['0']['Code'] === "Ok"){
Log::info("TenSms_LoginSmsSend_Phone-{$phone}_Send_Success-".json_encode($resp));
return true;
}
//短信发送失败将返回结果写入日志
Log::error("TenSms_LoginSmsSend_Phone-{$phone}_Send-Exception-".json_encode($resp));
//将异常写入日志
}catch (TencentCloudSDKException $e){
Log::error("TenSms_LoginSmsSend_Phone-{$phone}_Send_Exception-".$e->getMessage());
}
return false;
}
}
- ClassArr短信类集合
<?php
/**
* PHP version 7.1
*
* @date 2022-01-15 09:55:36
* @author xiangyang <827544120@qq.com>
*/
/**
* End file ClassArr.php
*/
namespace app\common\lib;
class ClassArr
{
public static function smsClassStat()
{
return [
'Ali' => 'app\common\lib\sms\AliSms',
'Ten' => 'app\common\lib\sms\TenSms',
];
}
public static function initClass($type, $class, $params = [], $sendIns = false)
{
if (!array_key_exists($type, $class)) {
return false;
}
$classObject = $class[$type];
return $sendIns == true ? (new \ReflectionClass($classObject))->newInstanceArgs($params) : $classObject;
}
}
- SmsBusiness短信验证码公共方法
<?php
/**
* PHP version 7.1
*
* @date 2021-12-16 15:56:28
* @author xiangyang <827544120@qq.com>
*/
/**
* End file SmsBusiness.php
*/
declare(strict_types=1);
namespace app\common\business\api;
use app\common\lib\ClassArr;
use app\common\lib\sms\AliSms;
class SmsBusiness
{
/**
*
* bus商城用户登录发送短信验证码,发送成功后写入Redis
* @method LoginSmsSend
* 发送短信
* @param array $data 手机号
* @param int $code 短信内容
* @param string $templateCode 短信模板ID
* @param string $signName 短信签名
*
* @return bool
* @throws \AlibabaCloud\Client\Exception\ClientException
*
* @author xiangyang <827544120@qq.com>
*/
public function LoginSmsSend(array $data, array $codeDataArray, string $code,string $templateCode, string $signName,string $type = 'ten'): bool {
$type = ucfirst($type);
$ClassArr = new ClassArr();
$smsObject = $ClassArr::smsClassStat();
$smsSend = $ClassArr::initClass($type, $smsObject);
$results = $smsSend::SmsSend($data['phone'], $codeDataArray, $templateCode, $signName);
if ($results) {
//发送成功
return true;
}
//发送失败
return false;
}
/**
* 短信参数格式化(因平台不一样所以短信的数据格式会有差异)
* @param int $code 随机验证码
* @param string $type 短信平台 ten=>TenSms;ali=>AliSms
* @return array
*/
public function LoginSmsParameter(int $code, string $type = 'ten'): array
{
if (strcasecmp($type, 'ali') == 0) {
$codeDataArray = [
'code' => $code,
];
$result = [
'code'=> $code,
'code_data_array' => $codeDataArray,
'templateCode' => config("Ali.templateCode.login"),
'signName' => config("Ali.signName.mall"),
];
return $result;
}else if(strcasecmp($type,'ten') == 0 ){
$codeDataArray = array((string)$code);
$result = [
'code'=>$code,
'code_data_array'=>$codeDataArray,
'templateCode'=>config("Ten.sms.template_id.login"),
'signName'=>config("Ten.sms.sign_name.1"),
];
return $result;
}
return [];
}
}
- 短信验证码调用
<?php
/**
* PHP version 7.1
*
* @date 2021-12-16 15:52:25
* @author xiangyang <827544120@qq.com>
*/
/**
* End file Sms.php
*/
namespace app\api\controller;
use app\BaseController;
use app\common\business\api\SmsBusiness;
use app\Request;
use think\facade\Log;
class Sms extends BaseController
{
/**
*
* 用户登录发送短信验证码
* @method LoginSmsSend
*
* @param Request $request
*
* @return \think\response\Json
*
* @author xiangyang <827544120@qq.com>
*/
public function LoginSmsSend(Request $request)
{
//获取手机号
$phone = $request->param("phone_number", null);
$data = [
'phone' => $phone,
];
try {
$SmsBusiness = new SmsBusiness();
//短信验证码内容
$code =100666 ;
//短信验证码 发送方
$type = 'ali';
//发送内容整理
$smsResult = $SmsBusiness->LoginSmsParameter($code,$type);
//发送短信
if(!empty($smsResult)){
$result = $SmsBusiness->LoginSmsSend($data,$smsResult['code_data_array'], $code,$smsResult['templateCode'],$smsResult['signName'],$type);
if ($result) {
return show(1, "短信验证码发送成功!");
}
}
} catch (\Exception $exception) {
Log::error("Sms_loginSmsSend_{$data['phone']}_exception-" . $exception->getMessage());
}
return show(0, "短信验证码发送失败!");
}
}
结语:短信验证码在发送短信的时候应该验证该手机号是否合法,验证码内容应该使用随机函数。