// +----------------------------------------------------------------------

// | ShopXO 国内领先企业级B2C免费开源电商系统

// +----------------------------------------------------------------------

// | Copyright (c) 2011~2019 http://shopxo.net All rights reserved.

// +----------------------------------------------------------------------

// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )

// +----------------------------------------------------------------------

// | Author: Devil

// +----------------------------------------------------------------------

namespace base;

/**

* 短信驱动

* @author liuyi

* @blog http://ourbrnader.com/

* @version 0.0.1

* @datetime 2020-05-18

*/

class TencentSms

{

// 保存错误信息

public $error;

// Access Key ID

private $accessKeyId = '';

// Access Access Key Secret

private $accessKeySecret = '';

// 签名

private $signName = '';

private $apiHost = "sms.tencentcloudapi.com";

//短信平台返回的原始数据

public $rawData;

/**

* [__construct 构造方法]

* @param [int] $param['interval_time'] [间隔时间(默认30)单位(秒)]

* @param [int] $param['expire_time'] [到期时间(默认30)单位(秒)]

* @param [string] $param['key_prefix'] [验证码种存储前缀key(默认 空)]

* @version 0.0.1

* @datetime 2017-03-07T14:03:02+0800

* @author Devil

* @blog http://gong.gg/

*/

public function __construct()

{

$this->signName = MyC('common_sms_sign');

$this->accessKeyId = MyC('common_sms_apikey');

$this->accessKeySecret = MyC('common_sms_apisecret');

$this->platform_appid = MyC('common_sms_sdk_appid');

}

/**

* 签名

*

* @param unknown $parameters

* @param unknown $accessKeySecret

* @return string

*/

private function computeSignature($host, $payload, $timestamp)

{

$secretId = $this->accessKeyId;

$secretKey = $this->accessKeySecret;

$service = 'sms';

$algorithm = "TC3-HMAC-SHA256";

$httpRequestMethod = 'POST';

$canonicalUri = "/";

$canonicalQueryString = "";

$canonicalHeaders = "content-type:application/json\n" . "host:" . $host . "\n";

$signedHeaders = "content-type;host";

// $payload = json_encode($param,JSON_UNESCAPED_UNICODE);

// echo $payload.PHP_EOL;

$hashedRequestPayload = hash("SHA256", $payload);

$canonicalRequest = $httpRequestMethod . "\n"

. $canonicalUri . "\n"

. $canonicalQueryString . "\n"

. $canonicalHeaders . "\n"

. $signedHeaders . "\n"

. $hashedRequestPayload;

// echo $canonicalRequest.PHP_EOL;

// step 2: build string to sign

$date = gmdate("Y-m-d", $timestamp);

$credentialScope = $date . "/" . $service . "/tc3_request";

$hashedCanonicalRequest = hash("SHA256", $canonicalRequest);

$stringToSign = $algorithm . "\n"

. $timestamp . "\n"

. $credentialScope . "\n"

. $hashedCanonicalRequest;

// echo $stringToSign.PHP_EOL;

// step 3: sign string

$secretDate = hash_hmac("SHA256", $date, "TC3" . $secretKey, true);

$secretService = hash_hmac("SHA256", $service, $secretDate, true);

$secretSigning = hash_hmac("SHA256", "tc3_request", $secretService, true);

$signature = hash_hmac("SHA256", $stringToSign, $secretSigning);

// echo $signature.PHP_EOL;

// step 4: build authorization

$authorization = $algorithm

. " Credential=" . $secretId . "/" . $credentialScope

. ", SignedHeaders=content-type;host, Signature=" . $signature;

// echo $authorization.PHP_EOL;

return $authorization;//返回认证签名

}

/**

* 短信发送

* @param [string] $mobile [手机号码,多个以 英文逗号 , 分割]

* @param [string|array] $code [变量code(单个直接传入 code 即可,多个传入数组)]

* @param [string] $template_code [模板 id]

* @param [boolean] $sign_name [自定义签名,默认使用基础配置的签名]

* @author Devil

* @blog http://gong.gg/

* @version 1.0.0

* @date 2020-04-02

* @desc description

*/

public function SendCode($mobile, $code, $template_code, $sign_name = '')

{

// 签名

$sign_name = empty($sign_name) ? $this->signName : $sign_name;

// 请求参数

$params = array( //此处作了修改

'PhoneNumberSet' => $mobile,

'TemplateID' => $template_code,

'Sign' => $sign_name,

'TemplateParamSet' => $code,

'SessionContext' => '',

'SmsSdkAppid' => $this->platform_appid

);

// 计算签名并把签名结果加入请求参数

$timestamp = time();

$url = 'https://' . $this->apiHost;

$version = '2019-07-11';

$action = "SendSms";

$payload = json_encode($params, JSON_UNESCAPED_UNICODE);

$authorization = $this->computeSignature($this->apiHost, $payload, $timestamp);

$headers = array(

"Authorization:$authorization",

"Content-type:application/json",

"Host:$this->apiHost",

"X-TC-Action:$action",

"X-TC-Version:$version",

"X-TC-Timestamp:$timestamp",

// "X-TC-Region:$region"

);

$curl = curl_init();

curl_setopt($curl, CURLOPT_URL, $url);

curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);

curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);

curl_setopt($curl, CURLOPT_AUTOREFERER, 1);

curl_setopt($curl, CURLOPT_POST, 1);

curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);

curl_setopt($curl, CURLOPT_POST, 1);

$result = curl_exec($curl);

curl_close($curl);

if ($result == false) {

$this->error = "访问腾讯云短信服务失败";

} else {

$result = json_decode($result, true);

}

//因为一般业务情况是发给一个人,这里就简单处理为取第一个短信的状态。

//如果是批量的话,需要遍历获得所有的情况,这样的可以另外写一个接口。

$this->rawData = $result;

if (isset($result["Response"]['Error'])) {

$errorCode = $result["Response"]['Error']['Code'];

} else if (isset($result["Response"]["SendStatusSet"][0])) {

$sendStatusItem = $result["Response"]["SendStatusSet"][0];

$errorCode = $sendStatusItem['Code'];

} else {

$errorCode = '';

}

if (strtolower($errorCode) != 'ok') {

$this->error = $this->getErrorMessage($errorCode);

return false;

}

return true;

}

/**

* 获取详细错误信息

*

* @param unknown $status

*/

public function getErrorMessage($status)

{

//查询错误码地址:

//https://cloud.tencent.com/document/product/382/38780

$message = array(

'FailedOperation.ContainSensitiveWord' => '短信内容中含有敏感词',

'FailedOperation.FailResolvePacket' => '请求包解析失败,通常情况下是由于没有遵守 API 接口说明规范导致的',

'FailedOperation.InsufficientBalanceInSmsPackage' => '套餐包余量不足',

'FailedOperation.JsonParseFail' => '解析请求包体时候失败',

'FailedOperation.MarketingSendTimeConstraint' => '营销短信发送时间限制,为避免骚扰用户,营销短信只允许在8点到22点发送。',

'FailedOperation.MissingSignature' => '没有申请签名之前,无法申请模板,请根据 创建签名 申请完成之后再次申请。',

'FailedOperation.PhoneNumberInBlacklist' => '手机号在黑名单库中,通常是用户退订或者命中运营商黑名单导致的,可联系 sms helper 解决。',

'FailedOperation.PhoneNumberOnBlacklist' => '手机号在黑名单库中,通常是用户退订或者命中运营商黑名单导致的,可联系 sms helper 解决。',

'InternalError.RequestTimeException' => '请求发起时间不正常,通常是由于您的服务器时间与腾讯云服务器时间差异超过10分钟导致的,请核对服务器时间及 API 接口中的时间字段是否正常。',

'InternalError.Timeout' => '请求下发短信超时,请参考 60008错误详解。',

'InvalidParameterValue.IncorrectPhoneNumber' => '手机号格式错误,请参考 1016错误详解',

'InvalidParameterValue.ProhibitedUseUrlInTemplateParameter' => '禁止在模板变量中使用 URL。',

'InvalidParameterValue.TemplateParameterFormatError' => '验证码模板参数格式错误,验证码类模版,模版变量只能传入0 - 6位(包括6位)纯数字',

'LimitExceeded.AppDailyLimit' => '业务短信日下发条数超过设定的上限 ,可自行到控制台调整短信频率限制策略。',

'LimitExceeded.DailyLimit' => '短信日下发条数超过设定的上限 (国际/港澳台),如需调整限制,可联系 sms helper。',

'LimitExceeded.DeliveryFrequencyLimit' => '下发短信命中了频率限制策略,可自行到控制台调整短信频率限制策略,如有其他需求请联系 sms helper。',

'LimitExceeded.PhoneNumberCountLimit' => '调用短信发送 API 接口单次提交的手机号个数超过200个',

'LimitExceeded.PhoneNumberDailyLimit' => '单个手机号日下发短信条数超过设定的上限,可自行到控制台调整短信频率限制策略。',

'LimitExceeded.PhoneNumberOneHourLimit' => '单个手机号1小时内下发短信条数超过设定的上限,可自行到控制台调整短信频率限制策略。',

'LimitExceeded.PhoneNumberSameContentDailyLimit' => '单个手机号下发相同内容超过设定的上限,可自行到控制台调整短信频率限制策略。',

'LimitExceeded.PhoneNumberThirtySecondLimit' => '单个手机号30秒内下发短信条数超过设定的上限,可自行到控制台调整短信频率限制策略。',

'MissingParameter.EmptyPhoneNumberSet' => '传入的号码列表为空,请确认您的参数中是否传入号码。',

'UnauthorizedOperation.IndividualUserMarketingSmsPermissionDeny' => '个人用户没有发营销短信的权限',

'UnauthorizedOperation.RequestIpNotInWhitelist' => '请求 IP 不在白名单中,您配置了校验请求来源 IP,但是检测到当前请求 IP 不在配置列表中,',

'UnauthorizedOperation.SerivceSuspendDueToArrears' => '欠费被停止服务,可自行登录腾讯云充值来缴清欠款。',

'ContainDomesticAndInternationalPhoneNumber' => '群发请求里既有国内手机号也有国际手机号。',

'UnsupportedOperation.UnsuportedRegion' => '不支持该地区短信下发。',

);

if (isset ($message [$status])) {

return $message [$status];

}

return '错误状态码:' . $status . ',详细错查询:https://cloud.tencent.com/document/product/382/38780';

}

}

?>

一键复制

编辑

原始数据

按行查看

历史

星模php格,extend/base/TencentSms.php · 纵之格/ShopXO - Gitee.com相关推荐

  1. 星模php格,Mostar三位“星模”演绎香奈儿梦幻古希腊

    Chanel 在天府之国成都,再现 2017/2018 早春度假系列,以多元文化创意区"东郊记忆"内的锦颂东方艺术展览中心作为发布会秀场,完美再现了2018早春度假系列. 超豪华明 ...

  2. android 绘制5格电量,Android 如何把状态栏信号格改为5格

    前言         欢迎大家我分享和推荐好用的代码段~~声明         欢迎转载,但请保留文章原始出处: CSDN:http://www.csdn.net 雨季o莫忧离:http://blog ...

  3. android 绘制5格电量,Android 怎么把状态栏信号格改为5格

    Android 如何把状态栏信号格改为5格 前言         欢迎大家我分享和推荐好用的代码段~~声明         欢迎转载,但请保留文章原始出处: CSDN:http://www.csdn. ...

  4. excel 某个单元格不是等于空值_excel 单元格为空与不存在

    Q3:Excel单元格为空怎么表示啊 一.在EXCEL中判断单元格是否为空单元可以用ISBLANK函数,也可以用某单元格是否=""来进行判断. 比如要判断A1单元格是否为空单元格, ...

  5. Swift - 可编辑表格样例(可直接编辑单元格中内容、移动删除单元格)

    (本文代码已升级至Swift3) 本文演示如何制作一个可以编辑单元格内容的表格(UITableView). 1,效果图 (1)默认状态下,表格不可编辑,当点击单元格的时候会弹出提示框显示选中的内容. ...

  6. ppwjs之bootstrap表格:String.到表头单元格元素 和 String.到表格单元格元素

    2019独角兽企业重金招聘Python工程师标准>>> <!DOCTYPT html> <html><head><meta http-equ ...

  7. asp.net gridview删除 获取到第一行第一列的单元格内容_VBA中的常用单元格引用方式...

    VBA编程经常和"对象"打交道,其中最频繁的对象大概就是"单元格"了.(听说您还没有对象?那--我想你大概需要一份Excel,包邮988--) 今天我们就来聊一 ...

  8. table合并单元格_制作课程表3——合并单元格

    由于浏览器兼容问题,. 以及 很少被使用, 所以我们将课程表依然使用tr.td元素,结合样式实现出前面案例中效果 原来代码: 课程1 课程2 课程3 课程4 课程5 课程1 课程2 课程3 课程4 课 ...

  9. java读取合并单元格_Java POI常用方法,读取单元格的值,设置单元格格式,合并单元格,获取已合并的单元格,导出至本地等...

    一.设置单元格格式. 设置单元格边框.单元格背景颜色.单元格对齐方式.单元格字体,设置自动换行. /** Description: 设置单元格格式. * @author : ys. * @date : ...

最新文章

  1. GSMA:中国有望成为全球领先的5G市场之一
  2. 华为eNSP安装使用教程 故障解决
  3. 【项目实战课】微信小程序图像识别模型前后端部署实战
  4. 祝贺王远当选为中国区第二位 Teams MVP
  5. Hive 外部表关联分区数据
  6. (转)令人无法理解的死锁案例分析
  7. oracle按用户采集信息,oracle 11g 手动收集用户统计信息
  8. vscode还用装git_使用vscode实现git同步
  9. 冰蝎2流量分析,解密以及其防守姿势
  10. Cannot pull, git cannot resolve reference ORIG_HEAD
  11. C++ 中的线程库和 lamber 表达式
  12. .NET应用程序安全操作概述
  13. 有关计算机启动过程的书籍,操作系统—计算机的启动过程
  14. uniapp如何使用微信小程序的订阅信息推送消息给用户?
  15. 一加3 android 8.0,OnePlus 3公测版固件完整rom包Android 8.0第15版
  16. AutoCAD字库的用法?
  17. 广联达需要的计算机系统配置,广联达bim安装算量软件对电脑要求配置高吗?
  18. ansys施加多步载荷
  19. 走过的路-java源码阅读之路
  20. c语言程序设计a题库,c语言程序设计试题(A).doc

热门文章

  1. java铃声类_MediaPlayer.setDataSource中的java.lang.IllegalStateException,使用铃声类
  2. mysql100个优化技巧_完整篇:100+个MySQL调试和优化技巧(2)
  3. db2 某个字段排序_MySQL、Oracle、DB2等数据库常规排序、自定义排序和按中文拼音字母排序...
  4. python cv.imread_Python的OpenCV cv2.imread总是返回None而cvFeatDetector崩溃了python
  5. V210 UART TX 流程
  6. ubuntu 修改用户名和计算机名称
  7. WinCE6.0 修改开机Logo方法
  8. 650c公路车推荐_盘点2020年各价位高性价比入门公路车
  9. 神经网络与深度学习——TensorFlow2.0实战(笔记)(二)(Anaconda软件介绍)
  10. 【转】DICOM通信 - PDU数据包(1)