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

浏览:2182 发布日期:2018/06/04 分类:用法示例 关键字: 阿里云短信 短信接口 阿里大鱼
如有疑问,请留言,或者加QQ群交流:193569204

以下可完美解决阿里云最新版本的短信通知类发送。还有效的控制刷短信操作。
application/common 下自定义文件:Alisms.php<?php
/**
 * Dabuba System 大布吧系统
 *
 * ====================================================================
 * @link      http://www.dabuba.com/
 * @copyright Copyright (c) 2016 Dabuba.com All rights reserved.
 * @license   http://www.apache.org/licenses/LICENSE.-2.0
 * ====================================================================
 *
 * @package     阿里云短信公共类
 *
 * @subpackage  阿里云短信验证码发送类
 *
 * @author      Tggui
 *
 */
namespace app\common;
use think\Controller;

class Alisms extends Controller
{
    // 保存错误信息
    public $error;
    // Access Key ID
    private $accessKeyId    = '';
    // Access Access Key Secret 
    private $accessKeySecret= '';
    //短信签名  阿里云短信服务里面申请的那个 
    private $aliProduct     = '';
    
    public function __construct() 
    {
        // 配置参数 去阿里云获取
        $this -> accessKeyId      = 'xxxx';
        $this -> accessKeySecret  = 'xxxx';
        $this -> aliProduct       = 'xxxx';
    }
    
    private function percentEncode($string) {
        $string = urlencode ( $string );
        $string = preg_replace ( '/\+/', '%20', $string );
        $string = preg_replace ( '/\*/', '%2A', $string );
        $string = preg_replace ( '/%7E/', '~', $string );
        return $string;
    }
    
    /**
     * 签名
     *
     * @param unknown $parameters            
     * @param unknown $accessKeySecret            
     * @return string
     */
    private function computeSignature($parameters, $accessKeySecret) {
        ksort ( $parameters );
        $canonicalizedQueryString = '';
        foreach ( $parameters as $key => $value ) {
            $canonicalizedQueryString .= '&' . $this->percentEncode ( $key ) . '=' . $this->percentEncode ( $value );
        }
        $stringToSign = 'GET&%2F&' . $this->percentencode ( substr ( $canonicalizedQueryString, 1 ) );
        $signature = base64_encode ( hash_hmac ( 'sha1', $stringToSign, $accessKeySecret . '&', true ) );
        return $signature;
    }
    
    /**
     * 发送短信
     *
     * @param string $mobile 手机号码
     * @param string $type 类型
     * @param int $create_id 操作人menber_id
     * @return bool 返回状态
     */
    public function sendSms( $mobile, $type, $create_id = 0 ) 
    {
        $returnArr      = [];
        $returnArr['status']    = 0;
        //判断是否能发送
        $isSend_time    = model('sms') -> isSend( $mobile );
        //请等待多少秒后才能重新获取短信验证码
        if ( !empty($isSend_time) ) {
            $returnArr['time']  = $isSend_time;
            return $returnArr;
        }
        //获取短信模板信息
        $tempCodeArr    = $this -> tempCode($type);
        //写入数据库
        $addData        = ['create_id' => $create_id, 'mobile' => $mobile, 'code' => $tempCodeArr['sms_code'], 'create_time' => time()];
        $sms_id         = model('sms') -> insertGetId($addData);
        if ($sms_id) {
            $params     = [
                'SignName'          => $tempCodeArr['signName'],
                'Format'            => 'JSON',
                'Version'           => '2017-05-25',
                'AccessKeyId'       => $this -> accessKeyId,
                'SignatureVersion'  => '1.0',
                'SignatureMethod'   => 'HMAC-SHA1',
                'SignatureNonce'    => uniqid(),
                'Timestamp'         => gmdate( 'Y-m-d\TH:i:s\Z' ),
                'Action'            => 'SendSms',
                'TemplateCode'      => $tempCodeArr['TemplateCode'],
                'PhoneNumbers'      => $mobile,
                'TemplateParam'     => '{"code":"' . $tempCodeArr['sms_code'] . '"}'
            ];
            // 计算签名并把签名结果加入请求参数
            $params ['Signature']   = $this -> computeSignature ( $params, $this -> accessKeySecret );
            //请求的接口
            $url    = 'http://dysmsapi.aliyuncs.com/?' . http_build_query ( $params );
            //公共方法的curl
            dbb_curl( $url, null, $result );
            //将json转换数组
            $result = json_decode ( $result, true );
            /**
             * 返回数据的大概格式
             *  [
                  'Message'     => "OK"
                  'RequestId'   => "xxxx"
                  'BizId'       => "xxxxxx"
                  'Code'        => "OK"
                ]
            */
            //以下自己写严谨点 我大概给个示例
            if ( $result ['Code'] == 'OK' ) {
                //存在 更新数据库
                $rs_update  = model('sms') -> sendUpdate($sms_id, $result['RequestId']);
                if ($rs_update) {
                    $returnArr['status'] = 1;
                }
            }
            //错误信息
//          return $this->error = $this->getErrorMessage($status)
        }
        return $returnArr;
    }
    
    /**
     * 短信模板
     */
    private function tempCode( $type ) 
    {
        //短信签名
        $product  = $this -> aliProduct;
        //随机4位 + 2(66/88)
        $code_arr = array('66','88');
        $sms_code = random('4','2356789').$code_arr[array_rand($code_arr,1)];
        switch ($type) {
            //模板1
            case 1 : 
                $TemplateCode = "SMS_xxx01";
                break;
            //模板2
            case 2 : 
                $TemplateCode = "SMS_xxx02";
                break;
        }
        return [ 'sms_code' => $sms_code, 'TemplateCode' => $TemplateCode, 'signName' => $product ];
    }

    /**
     * 获取详细错误信息
     *
     * @param unknown $status            
     */
    public function getErrorMessage( $status )
    {
        $message    = [
            'isv.InvalidDayuStatus.Malformed'           => '账户短信开通状态不正确',
            'isv.InvalidSignName.Malformed'             => '短信签名不正确或签名状态不正确',
            'isv.InvalidTemplateCode.MalFormed'         => '短信模板Code不正确或者模板状态不正确',
            'isv.InvalidRecNum.Malformed'               => '目标手机号不正确,单次发送数量不能超过100',
            'isv.InvalidParamString.MalFormed'          => '短信模板中变量不是json格式',
            'isv.InvalidParamStringTemplate.Malformed'  => '短信模板中变量与模板内容不匹配',
            'isv.InvalidSendSms'                        => '触发业务流控',
            'isv.InvalidDayu.Malformed'                 => '变量不能是url,可以将变量固化在模板中' 
        ];
        if (isset ( $message [$status] )) {
            return $message [$status];
        }
        return $status;
    }
}
以上代码只需要改三个参数和tempCode的模板就可以了。

相关方法:

common.php/**
 * 发送短信
 *
 * @param string $mobile 手机号码
 * @param string $type 类型:1-用户注册验证码、2-修改密码验证码
 * @param int $create_id 操作人menber_id
 * @return bool 返回状态
 */
function smsSend($mobile, $type, $create_id, $ParamArr='')
{
    $aliSms = new \app\common\AliSms();
    return $aliSms->sendSms($mobile, $type, $create_id, $ParamArr);
}

/**
 * 通过CURL获取远程服务器数据
 * @param string $url 远程服务器URL
 * @param json $data POST数据
 * @param mixed $output 返回值
 * @param array $header 传递头部信息
 * @return mixed
 */
function dbb_curl($curr_url, $data = null, &$output, $header = null)
{
    $ch = curl_init();
    if (!$header) {
        $header = ["Accept-Charset: utf-8"];
    }
    curl_setopt($ch, CURLOPT_URL, $curr_url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//     curl_setopt($ch, CURLOPT_HEADER, true); //获取头部信息
    if (1 == strpos("$".$curr_url, "https://")) {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    }
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
    if (!empty($data)){
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }
    $output     = curl_exec($ch);
    $errorno    = curl_errno($ch);
    curl_close($ch);
    if ($errorno) {
        return $errorno;
    }else{
        return 0;
    }
}
sms的model类相关方法:    /**
     * 判断是否能发送
     *
     * @param array $data 创建人ID、手机号码、验证码
     * @return int 下次获取等待时间
     */
    public function isSend($mobile)
    {
        $last_create_time = $this->where("mobile='$mobile'")->order('id DESC')->value('create_time');
        if (empty($last_create_time)) {
            return 0;
        }
        $curr_time = time();
        $interval_time = getConfig('interval_time')?getConfig('interval_time'):60;//间隔时间
        $surplus = $curr_time - $last_create_time;
        if ( $surplus > $interval_time ) {
            return 0;
        } else {
            return intval(($interval_time - $surplus));
        }
    }

    /**
     * 发送结果更新
     *
     * @param array $data 创建人ID、手机号码、验证码
     * @return int 下次获取等待时间
     */
    public function sendUpdate($id, $requestid)
    {
        $updata_arr = array('status'=>1, 'requestid'=>$requestid, 'update_time'=>time());
        return $this->where("id=$id")->update($updata_arr);
    }

    //============== 以下两个方法本文没使用到,可参考 ==============
    /**
     * 验证码校验
     *
     * @param string $mobile 手机号码
     * @param string $code 验证码
     * @return array 校验结果
     */
    public function check_code($mobile, $code)
    {
        $return_arr = array('status'=>0,'msg'=>'');
        $rs = $this->field('id,is_use,create_time')->where("status=1 AND mobile=$mobile AND code=$code")->order('id DESC')->find();
        if ($rs) {
            if ($rs['is_use']==1) {
                $return_arr['msg'] = '该验证码已经被使用';
            }
            $invalidTime    =    getConfig('code_invalid_time') ? getConfig('code_invalid_time') : 600;
            if ( (time() - $rs['create_time']) > $invalidTime ) {
                $return_arr['msg'] = '该验证码已经失效';
            }
            if (empty($return_arr['msg'])) {
                $return_arr['status'] = 1;
                $return_arr['msg'] = '验证通过';
                $return_arr['id'] = $rs['id'];
            }
        } else {
            $return_arr['msg'] = '验证码错误';
        }
        return $return_arr;
    }
    
    /**
     * 标记验证码已经被使用
     *
     * @param int $id 验证码ID
     * @return bool
     */
    public function code_use($id)
    {
        $data = array('is_use'=>1, 'update_time'=>time());
        return $this->where('id',$id)->update($data);
    }
表结构:-- ----------------------------
-- Table structure for dbb_sms
-- ----------------------------
DROP TABLE IF EXISTS `dbb_sms`;
CREATE TABLE `dbb_sms` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '短信ID',
  `status` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '发送状态:0-发送中、1-发送成功',
  `mobile` char(15) NOT NULL DEFAULT '' COMMENT '手机号码',
  `code` char(6) NOT NULL DEFAULT '' COMMENT '验证码',
  `requestid` char(40) NOT NULL DEFAULT '' COMMENT '返回请求id',
  `is_use` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '使用状态:0-未使用、1-已经使用',
  `create_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建人ID',
  `create_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
  `update_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `mobile` (`id`,`code`) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=632 DEFAULT CHARSET=utf8 COMMENT='短信发送记录表';
在任意一个控制器直接使用://根据方法来填参数即可 sendSms( $mobile, $type, $create_id ) 
$returnArr = smsSend('手机号', 1, 8);
halt($returnArr);
其他流程看自己需求来写。
评论( 相关
后面还有条评论,点击查看>>