一、对短信工厂结构进行了修改
1、短信发送父类追加了批量发送
<?php
/**
* 短信发送父类
* User: 龙哥 三年风水
* Date: 2024/12/1/0001
* Time: 15:52
*/
namespace Sms;
interface SmsSenderInterface
{
/**
* 单条短信发送
* 内部json处理过
* User: 龙哥·三年风水
* Date: 2024/12/1/0001
* Time: 15:52
* @ param $mobile 要发送的对象
* @ param $templateCode 模板编号
* @ param $templateParam 模板对应参数
* @ param string $signName 签名(如果需要采用不同的签名才需要传参)
* @ return mixed
*/
public static function send($mobile,$templateCode,$templateParam,$signName = '');
/**
* 批量短信发送
* 内部json处理过,单个模板,单个签名
* User: 龙哥·三年风水
* Date: 2024/12/2
* Time: 13:42
* @ param $mobiles 要发送的对象,数组形式
* @ param $templateCode 要发送的模板
* @ param $templateParam 要发送的参数
* @ param string $signName 签名(如果需要采用不同的签名才需要传参)
* @ return mixed
*/
public static function batchSend($mobiles,$templateCode,$templateParam,$signName = '');
}
2、短信发送类实例工厂进行了修改
<?php
/**
* 创建短信发送类实例工厂
* User: 龙哥 三年风水
* Date: 2024/12/1/0001
* Time: 15:59
*/
namespace Sms;
use Sms\channel\AliyunSmsSender;
use Sms\channel\QiniuyunSmsSender;
use Sms\channel\TencentSmsSender;
use Error\BaseError;
use app\model\param\Emailsms;
use app\model\param\Sms;
class SmsSenderFactory
{
protected static $instance=null;//缓存实例
protected static $channel = [];//通道参数
/**
* 调用类实例
* User: 龙哥 三年风水
* Date: 2024/12/1/0001
* Time: 15:59
* @ return null|AliyunSmsSender|QiniuyunSmsSender|TencentSmsSender
*/
public static function create(){
$smsId = Emailsms::dataFind(['id' => 1],'sms_id');
if(empty($smsId) || empty($smsId['sms_id']))throw new BaseError("未设置任何短信发送通道",50000,200);
$resSms = Sms::dataFind(['id' => $smsId['sms_id']],'app_id,access_key_id,access_key_secret,sign_name,status',true);
if(empty($resSms) || empty($resSms['status']))throw new BaseError("短信发送通道已关闭",50000,200);
self::$channel = [
'app_id' => $resSms['app_id'],
'access_key_id' => $resSms['access_key_id'],
'access_key_secret' => $resSms['access_key_secret'],
'sign_name' => $resSms['sign_name']
];
switch ($smsId['sms_id']){
case 1:
self::$instance = new AliyunSmsSender(self::$channel);
break;
case 2:
self::$instance = new QiniuyunSmsSender(self::$channel);
break;
case 3:
self::$instance = new TencentSmsSender(self::$channel);
break;
default:
self::$instance = null;
throw new BaseError("未设置任何短信发送通道",50000,200);
break;
}
return self::$instance;
}
}
二、阿里云短信工厂开发
1、添加框架对应的SDK
composer require alibabacloud/dysmsapi-20170525
2、添加阿里云工厂
在根目录下extend文件夹下Sms文件夹下channel文件夹下,创建阿里云短信发送工厂并命名为AliyunSmsSender。记住,一定要在阿里云短信发送工厂类名后面去实现短信发送工厂。
<?php
/**
* 阿里云短信发送类
* User: 龙哥 三年风水
* Date: 2024/12/1/0001
* Time: 16:46
*/
namespace Sms\channel;
use AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi;
use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendSmsRequest;
use Darabonba\OpenApi\Models\Config;
use Error\BaseError;
use Sms\SmsSenderInterface;
class AliyunSmsSender implements SmsSenderInterface
{
protected static $signName = ""; //签名
protected static $smsClient = null; //客户端
public function __construct($param){
$config = new Config([
"accessKeyId" => $param['access_key_id'],
"accessKeySecret" => $param['access_key_secret']
]);
$config->endpoint = "dysmsapi.aliyuncs.com";
self::$smsClient = new Dysmsapi($config);
self::$signName = $param['sign_name'];
}
/**
* 单条短信发送
* 内部json处理过
* User: 龙哥·三年风水
* Date: 2024/12/1/0001
* Time: 15:52
* @ param $mobile 要发送的对象
* @ param $templateCode 模板编号
* @ param $templateParam 模板对应参数
* @ param string $signName 签名(如果需要采用不同的签名才需要传参)
* @ return mixed
*/
public static function send($mobile, $templateCode, $templateParam, $signName = '')
{
if(empty($mobile))throw new BaseError('手机号参数必须传',50000,200);
if(is_array($mobile) && count($mobile) >= 0)throw new BaseError('手机号参数只能是字符串方式',50000,200);
$sendSmsRequest = new SendSmsRequest([
"phoneNumbers" => $mobile,
"signName" => empty($signName) ? self::$signName : $signName,
"templateCode" => $templateCode,
"templateParam" => json_encode($templateParam)
]);
$res = self::$smsClient->sendSms($sendSmsRequest);
if($res->body->code != "OK")throw new BaseError($res->body->message,50000,200);
return true;
}
/**
* 批量短信发送
* 内部json处理过,单个模板,单个签名
* User: 龙哥·三年风水
* Date: 2024/12/2
* Time: 13:42
* @ param $mobiles 要发送的对象,数组形式
* @ param $templateCode 要发送的模板
* @ param $templateParam 要发送的参数
* @ param string $signName 签名(如果需要采用不同的签名才需要传参)
* @ return mixed
*/
public static function batchSend($mobiles, $templateCode, $templateParam, $signName = '')
{
if(!is_array($mobiles) || count($mobiles) == 0)throw new BaseError("批量发送,手机号码必须是数组",50000,200);
$signNames = [];
$templateParams = [];
for($i = 0; $i < count($mobiles); $i++){
array_push($signNames, empty($signName) ? self::$signName : $signName);
array_push($templateParams, $templateParam);
}
$sendSmsRequest = new SendSmsRequest([
"phoneNumberJson" => json_encode($mobiles),
"signNameJson" => json_encode($signNames),
"templateCode" => $templateCode,
"templateParamJson" => json_encode($templateParams)
]);
$res = self::$smsClient->sendBatchSms($sendSmsRequest);
if($res->body->code != "OK")throw new BaseError($res->body->message,50000,200);
return true;
}
}
三、测试
1、单条短信发送测试
<?php
namespace app\controller;
use Encipher\Encrypt;
use Sms\SmsSenderFactory;
class Index extends Emptys
{
public function index()
{
$smsSender = SmsSenderFactory::create();
$smsSender::send('15088888888','SMS_185455555',['code' => 1234]);
return succ('操作成功');
}
}
2、批量短信发送测试
<?php
namespace app\controller;
use Encipher\Encrypt;
use Sms\SmsSenderFactory;
class Index extends Emptys
{
public function index()
{
$smsSender = SmsSenderFactory::create();
$smsSender::batchSend(['15088888888','15188888888'],'SMS_185455555',['code' => 1234]);
return succ('操作成功');
}
}