最新版本的阿里云短信,不需要sdk,带防刷机制【转】

http://www.thinkphp.cn/code/4414.html

如有疑问,请留言,或者加QQ群交流:193569204

以下可完美解决阿里云最新版本的短信通知类发送。还有效的控制刷短信操作。
application/common 下自定义文件:Alisms.php

  1. <?php
  2. /**
  3.  * Dabuba System 大布吧系统
  4.  *
  5.  * ====================================================================
  6.  * @link      http://www.dabuba.com/
  7.  * @copyright Copyright (c) 2016 Dabuba.com All rights reserved.
  8.  * @license   http://www.apache.org/licenses/LICENSE.-2.0
  9.  * ====================================================================
  10.  *
  11.  * @package     阿里云短信公共类
  12.  *
  13.  * @subpackage  阿里云短信验证码发送类
  14.  *
  15.  * @author      Tggui
  16.  *
  17.  */
  18. namespace app\common;
  19. use think\Controller;
  20.  
  21. class Alisms extends Controller
  22. {
  23.     // 保存错误信息
  24.     public $error;
  25.     // Access Key ID
  26.     private $accessKeyId    = '';
  27.     // Access Access Key Secret 
  28.     private $accessKeySecret= '';
  29.     //短信签名  阿里云短信服务里面申请的那个 
  30.     private $aliProduct     = '';
  31.     
  32.     public function __construct() 
  33.     {
  34.         // 配置参数 去阿里云获取
  35.         $this -> accessKeyId      = 'xxxx';
  36.         $this -> accessKeySecret  = 'xxxx';
  37.         $this -> aliProduct       = 'xxxx';
  38.     }
  39.     
  40.     private function percentEncode($string) {
  41.         $string = urlencode ( $string );
  42.         $string = preg_replace ( '/\+/', '%20', $string );
  43.         $string = preg_replace ( '/\*/', '%2A', $string );
  44.         $string = preg_replace ( '/%7E/', '~', $string );
  45.         return $string;
  46.     }
  47.     
  48.     /**
  49.      * 签名
  50.      *
  51.      * @param unknown $parameters            
  52.      * @param unknown $accessKeySecret            
  53.      * @return string
  54.      */
  55.     private function computeSignature($parameters, $accessKeySecret) {
  56.         ksort ( $parameters );
  57.         $canonicalizedQueryString = '';
  58.         foreach ( $parameters as $key => $value ) {
  59.             $canonicalizedQueryString .= '&' . $this->percentEncode ( $key ) . '=' . $this->percentEncode ( $value );
  60.         }
  61.         $stringToSign = 'GET&%2F&' . $this->percentencode ( substr ( $canonicalizedQueryString, 1 ) );
  62.         $signature = base64_encode ( hash_hmac ( 'sha1', $stringToSign, $accessKeySecret . '&', true ) );
  63.         return $signature;
  64.     }
  65.     
  66.     /**
  67.      * 发送短信
  68.      *
  69.      * @param string $mobile 手机号码
  70.      * @param string $type 类型
  71.      * @param int $create_id 操作人menber_id
  72.      * @return bool 返回状态
  73.      */
  74.     public function sendSms( $mobile, $type, $create_id = 0 ) 
  75.     {
  76.         $returnArr      = [];
  77.         $returnArr['status']    = 0;
  78.         //判断是否能发送
  79.         $isSend_time    = model('sms') -> isSend( $mobile );
  80.         //请等待多少秒后才能重新获取短信验证码
  81.         if ( !empty($isSend_time) ) {
  82.             $returnArr['time']  = $isSend_time;
  83.             return $returnArr;
  84.         }
  85.         //获取短信模板信息
  86.         $tempCodeArr    = $this -> tempCode($type);
  87.         //写入数据库
  88.         $addData        = ['create_id' => $create_id, 'mobile' => $mobile, 'code' => $tempCodeArr['sms_code'], 'create_time' => time()];
  89.         $sms_id         = model('sms') -> insertGetId($addData);
  90.         if ($sms_id) {
  91.             $params     = [
  92.                 'SignName'          => $tempCodeArr['signName'],
  93.                 'Format'            => 'JSON',
  94.                 'Version'           => '2017-05-25',
  95.                 'AccessKeyId'       => $this -> accessKeyId,
  96.                 'SignatureVersion'  => '1.0',
  97.                 'SignatureMethod'   => 'HMAC-SHA1',
  98.                 'SignatureNonce'    => uniqid(),
  99.                 'Timestamp'         => gmdate( 'Y-m-d\TH:i:s\Z' ),
  100.                 'Action'            => 'SendSms',
  101.                 'TemplateCode'      => $tempCodeArr['TemplateCode'],
  102.                 'PhoneNumbers'      => $mobile,
  103.                 'TemplateParam'     => '{"code":"' . $tempCodeArr['sms_code'] . '"}'
  104.             ];
  105.             // 计算签名并把签名结果加入请求参数
  106.             $params ['Signature']   = $this -> computeSignature ( $params, $this -> accessKeySecret );
  107.             //请求的接口
  108.             $url    = 'http://dysmsapi.aliyuncs.com/?' . http_build_query ( $params );
  109.             //公共方法的curl
  110.             dbb_curl( $url, null, $result );
  111.             //将json转换数组
  112.             $result = json_decode ( $result, true );
  113.             /**
  114.              * 返回数据的大概格式
  115.              *  [
  116.                   'Message'     => "OK"
  117.                   'RequestId'   => "xxxx"
  118.                   'BizId'       => "xxxxxx"
  119.                   'Code'        => "OK"
  120.                 ]
  121.             */
  122.             //以下自己写严谨点 我大概给个示例
  123.             if ( $result ['Code'] == 'OK' ) {
  124.                 //存在 更新数据库
  125.                 $rs_update  = model('sms') -> sendUpdate($sms_id, $result['RequestId']);
  126.                 if ($rs_update) {
  127.                     $returnArr['status'] = 1;
  128.                 }
  129.             }
  130.             //错误信息
  131. //          return $this->error = $this->getErrorMessage($status)
  132.         }
  133.         return $returnArr;
  134.     }
  135.     
  136.     /**
  137.      * 短信模板
  138.      */
  139.     private function tempCode( $type ) 
  140.     {
  141.         //短信签名
  142.         $product  = $this -> aliProduct;
  143.         //随机4位 + 2(66/88)
  144.         $code_arr = array('66','88');
  145.         $sms_code = random('4','2356789').$code_arr[array_rand($code_arr,1)];
  146.         switch ($type) {
  147.             //模板1
  148.             case 1 : 
  149.                 $TemplateCode = "SMS_xxx01";
  150.                 break;
  151.             //模板2
  152.             case 2 : 
  153.                 $TemplateCode = "SMS_xxx02";
  154.                 break;
  155.         }
  156.         return [ 'sms_code' => $sms_code, 'TemplateCode' => $TemplateCode, 'signName' => $product ];
  157.     }
  158.  
  159.     /**
  160.      * 获取详细错误信息
  161.      *
  162.      * @param unknown $status            
  163.      */
  164.     public function getErrorMessage( $status )
  165.     {
  166.         $message    = [
  167.             'isv.InvalidDayuStatus.Malformed'           => '账户短信开通状态不正确',
  168.             'isv.InvalidSignName.Malformed'             => '短信签名不正确或签名状态不正确',
  169.             'isv.InvalidTemplateCode.MalFormed'         => '短信模板Code不正确或者模板状态不正确',
  170.             'isv.InvalidRecNum.Malformed'               => '目标手机号不正确,单次发送数量不能超过100',
  171.             'isv.InvalidParamString.MalFormed'          => '短信模板中变量不是json格式',
  172.             'isv.InvalidParamStringTemplate.Malformed'  => '短信模板中变量与模板内容不匹配',
  173.             'isv.InvalidSendSms'                        => '触发业务流控',
  174.             'isv.InvalidDayu.Malformed'                 => '变量不能是url,可以将变量固化在模板中' 
  175.         ];
  176.         if (isset ( $message [$status] )) {
  177.             return $message [$status];
  178.         }
  179.         return $status;
  180.     }
  181. }

复制代码

以上代码只需要改三个参数和tempCode的模板就可以了。

相关方法:

common.php

  1. /**
  2.  * 发送短信
  3.  *
  4.  * @param string $mobile 手机号码
  5.  * @param string $type 类型:1-用户注册验证码、2-修改密码验证码
  6.  * @param int $create_id 操作人menber_id
  7.  * @return bool 返回状态
  8.  */
  9. function smsSend($mobile, $type, $create_id, $ParamArr='')
  10. {
  11.     $aliSms = new \app\common\AliSms();
  12.     return $aliSms->sendSms($mobile, $type, $create_id, $ParamArr);
  13. }
  14.  
  15. /**
  16.  * 通过CURL获取远程服务器数据
  17.  * @param string $url 远程服务器URL
  18.  * @param json $data POST数据
  19.  * @param mixed $output 返回值
  20.  * @param array $header 传递头部信息
  21.  * @return mixed
  22.  */
  23. function dbb_curl($curr_url, $data = null, &$output, $header = null)
  24. {
  25.     $ch = curl_init();
  26.     if (!$header) {
  27.         $header = ["Accept-Charset: utf-8"];
  28.     }
  29.     curl_setopt($ch, CURLOPT_URL, $curr_url);
  30.     curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
  31.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  32. //     curl_setopt($ch, CURLOPT_HEADER, true); //获取头部信息
  33.     if (1 == strpos("$".$curr_url, "https://")) {
  34.         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  35.         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  36.     }
  37.     curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
  38.     if (!empty($data)){
  39.         curl_setopt($ch, CURLOPT_POST, 1);
  40.         curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  41.     }
  42.     $output     = curl_exec($ch);
  43.     $errorno    = curl_errno($ch);
  44.     curl_close($ch);
  45.     if ($errorno) {
  46.         return $errorno;
  47.     }else{
  48.         return 0;
  49.     }
  50. }

复制代码

sms的model类相关方法:

  1.     /**
  2.      * 判断是否能发送
  3.      *
  4.      * @param array $data 创建人ID、手机号码、验证码
  5.      * @return int 下次获取等待时间
  6.      */
  7.     public function isSend($mobile)
  8.     {
  9.         $last_create_time = $this->where("mobile='$mobile'")->order('id DESC')->value('create_time');
  10.         if (empty($last_create_time)) {
  11.             return 0;
  12.         }
  13.         $curr_time = time();
  14.         $interval_time = getConfig('interval_time')?getConfig('interval_time'):60;//间隔时间
  15.         $surplus = $curr_time - $last_create_time;
  16.         if ( $surplus > $interval_time ) {
  17.             return 0;
  18.         } else {
  19.             return intval(($interval_time - $surplus));
  20.         }
  21.     }
  22.  
  23.     /**
  24.      * 发送结果更新
  25.      *
  26.      * @param array $data 创建人ID、手机号码、验证码
  27.      * @return int 下次获取等待时间
  28.      */
  29.     public function sendUpdate($id, $requestid)
  30.     {
  31.         $updata_arr = array('status'=>1, 'requestid'=>$requestid, 'update_time'=>time());
  32.         return $this->where("id=$id")->update($updata_arr);
  33.     }
  34.  
  35.     //============== 以下两个方法本文没使用到,可参考 ==============
  36.     /**
  37.      * 验证码校验
  38.      *
  39.      * @param string $mobile 手机号码
  40.      * @param string $code 验证码
  41.      * @return array 校验结果
  42.      */
  43.     public function check_code($mobile, $code)
  44.     {
  45.         $return_arr = array('status'=>0,'msg'=>'');
  46.         $rs = $this->field('id,is_use,create_time')->where("status=1 AND mobile=$mobile AND code=$code")->order('id DESC')->find();
  47.         if ($rs) {
  48.             if ($rs['is_use']==1) {
  49.                 $return_arr['msg'] = '该验证码已经被使用';
  50.             }
  51.             $invalidTime    =    getConfig('code_invalid_time') ? getConfig('code_invalid_time') : 600;
  52.             if ( (time() - $rs['create_time']) > $invalidTime ) {
  53.                 $return_arr['msg'] = '该验证码已经失效';
  54.             }
  55.             if (empty($return_arr['msg'])) {
  56.                 $return_arr['status'] = 1;
  57.                 $return_arr['msg'] = '验证通过';
  58.                 $return_arr['id'] = $rs['id'];
  59.             }
  60.         } else {
  61.             $return_arr['msg'] = '验证码错误';
  62.         }
  63.         return $return_arr;
  64.     }
  65.     
  66.     /**
  67.      * 标记验证码已经被使用
  68.      *
  69.      * @param int $id 验证码ID
  70.      * @return bool
  71.      */
  72.     public function code_use($id)
  73.     {
  74.         $data = array('is_use'=>1, 'update_time'=>time());
  75.         return $this->where('id',$id)->update($data);
  76.     }

复制代码

表结构:

扫描二维码关注公众号,回复: 5421764 查看本文章
  1. -- ----------------------------
  2. -- Table structure for dbb_sms
  3. -- ----------------------------
  4. DROP TABLE IF EXISTS `dbb_sms`;
  5. CREATE TABLE `dbb_sms` (
  6.   `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '短信ID',
  7.   `status` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '发送状态:0-发送中、1-发送成功',
  8.   `mobile` char(15) NOT NULL DEFAULT '' COMMENT '手机号码',
  9.   `code` char(6) NOT NULL DEFAULT '' COMMENT '验证码',
  10.   `requestid` char(40) NOT NULL DEFAULT '' COMMENT '返回请求id',
  11.   `is_use` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '使用状态:0-未使用、1-已经使用',
  12.   `create_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建人ID',
  13.   `create_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
  14.   `update_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
  15.   PRIMARY KEY (`id`),
  16.   KEY `mobile` (`id`,`code`) USING BTREE
  17. ) ENGINE=MyISAM AUTO_INCREMENT=632 DEFAULT CHARSET=utf8 COMMENT='短信发送记录表';

复制代码

在任意一个控制器直接使用:

  1. //根据方法来填参数即可 sendSms( $mobile, $type, $create_id ) 
  2. $returnArr = smsSend('手机号', 1, 8);
  3. halt($returnArr);

复制代码

其他流程看自己需求来写。

猜你喜欢

转载自blog.csdn.net/hyb1234hi/article/details/87629475
今日推荐