[TOC] #### 1.引入 composr 包 ---- ``` composer require flc/dysms ``` #### 2. 阿里云短信服务验证码封装类 v1.0.1 --- ```php <?php // 本文件放入TP6.0的extend目录下 extend/Dysms.php use Flc\Dysms\Client; use Flc\Dysms\Request\SendSms; // 1.设置配置参数 Dysms::setConfig([ 'signName' => 'it社区', 'templateCode' => 'SMS_17929xxxx', 'accessKeyId' => 'LTAI4GJ6iaE7ij5YiGRgxxxx', 'accessKeySecret' => 'uljdxDoi8ocXNscPriqwl5xxxxx', ]); // 2.查看配置参数 //var_dump(Dysms::showConfig()); // 3.发送验证码 // $arr['result'] true 发送成功 msg 提示信息 verCode 发送的短信验证码 // ['result' => true, 'msg' => '发送成功', 'verCode' => 370449] // $arr['result'] false 发送失败 msg 错误信息 code 错误码 // ['result' => false, 'msg' => '错误信息', 'code' => 'isv.BUSINESS_LIMIT_CONTROL'] $arr = Dysms::sendSms(1503784xxxx); var_dump($arr); /** * 阿里大于短信验证码封装 * composer require flc/dysms * * @author liang <23426945@qq.com> * @version 1.0.1 * @homepage www.itqaq.com 辰风沐阳 * @datetime 2020-08-04 last modify time * * 阿里云短信服务默认流控 * 同一个签名同一个手机号短信验证码 1条/分钟 */ class Dysms { private static $accessKeyId; private static $accessKeySecret; private static $signName; private static $templateCode; /** * 私有化构造方法 * 禁止类在外部被实例化 */ private function __construct(){} /** * 设定配置参数 */ public static function setConfig($config) { // accessKeyId self::$accessKeyId = $config['accessKeyId']; // accessKeySecret self::$accessKeySecret = $config['accessKeySecret']; // 短信签名 self::$signName = $config['signName']; // 短信模板ID self::$templateCode = $config['templateCode']; } /** * 查看配置参数 * Dysms::showConfig() */ public static function showConfig() { return [ 'accessKeyId' => self::$accessKeyId, 'accessKeySecret' => self::$accessKeySecret, 'signName' => self::$signName, 'templateCode' => self::$templateCode, ]; } /** * 传入手机号发送短信验证码 * @param int $phoneNumbers 手机号 * @return array ['result' => true, 'msg' => '发送成功', 'verCode' => 370449] */ public static function sendSms($phoneNumbers) { $client = new Client([ 'accessKeyId' => self::$accessKeyId, 'accessKeySecret' => self::$accessKeySecret, ]); $sendSms = new SendSms; $verCode = mt_rand(100000, 999999); $sendSms->setPhoneNumbers($phoneNumbers); $sendSms->setSignName(self::$signName); $sendSms->setTemplateCode(self::$templateCode); $sendSms->setTemplateParam(['code' => $verCode]); $sendSms->setOutId('demo'); // 返回标准类对象 发送失败 // object(stdClass)#59 (3) { // ["Message"]=> // string(30) "触发小时级流控Permits:5" // ["RequestId"]=> // string(36) "B76061EE-2D9A-4E46-89B9-2418E8A5555E" // ["Code"]=> // string(26) "isv.BUSINESS_LIMIT_CONTROL" // } $result = $client->execute($sendSms); // 返回结果 // array(2) { // ["result"]=> // bool(true) // ["msg"]=> // string(12) "发送成功" // } // array(3) { // ["result"]=> // bool(false) // ["code"]=> // string(26) "isv.BUSINESS_LIMIT_CONTROL" // ["msg"]=> // string(30) "触发小时级流控Permits:5" // } if ($result->Code === 'OK') { return [ 'result' => true, 'msg' => '发送成功', 'verCode' => $verCode ]; } else { return [ 'result' => false, 'code' => $result->Code, 'msg' => self::errorMsg($result->Code, $result->Message) ]; } } /** * 错误信息code转换中文提示 */ private static function errorMsg($code, $msg) { $errorMsg = [ 'isv.ACCOUNT_NOT_EXISTS' => '使用了错误的账户名称或AK', 'isv.ACCOUNT_ABNORMAL' => '账户异常,请确认账号信息', 'isv.MOBILE_NUMBER_ILLEGAL' => '手机号码格式错误', 'isv.SMS_TEMPLATE_ILLEGAL' => '短信模板不存在,或未经审核通过', 'isv.SMS_SIGNATURE_ILLEGAL' => '短信签名不存在,或未经审核通过', 'isv.BUSINESS_LIMIT_CONTROL' => '短信发送频率超限', 'isv.AMOUNT_NOT_ENOUGH' => '当前账户余额不足,请及时充值', 'SignatureDoesNotMatch' => '签名加密错误,请注意accessKeyId和accessKeySecret字符串赋值正确', ]; return $errorMsg[$code] ?? $msg; } /** * 私有化克隆方法 * 禁止类的实例在外部被克隆 */ private function __clone(){} } ``` #### 3. 阿里云短信服务验证码封装函数 --- 将发送短信验证码封装为类感觉复杂化了,我又整理成了一个函数如下所示: 当验证码发送失败时,记录发送失败的错误信息日志,下面是我在 TP5.0 中记录日志的写法 ```php /** * 发送阿里云短信验证码 * @param $mobile 手机号 * @param $code 短信验证码 * @link https://www.aliyun.com/product/sms * @link https://packagist.org/packages/flc/dysms * @describe 基于 composer require flc/dysms 依赖包 */ function send_ali_sms($mobile, $code) { $config = [ 'signName' => '', 'templateCode' => '', 'accessKeyId' => '', 'accessKeySecret' => '', ]; $client = new \Flc\Dysms\Client([ 'accessKeyId' => $config['accessKeyId'], 'accessKeySecret' => $config['accessKeySecret'], ]); $sendSms = new \Flc\Dysms\Request\SendSms; $sendSms->setPhoneNumbers($mobile); $sendSms->setSignName($config['signName']); $sendSms->setTemplateCode($config['templateCode']); $sendSms->setTemplateParam(['code' => $code]); $sendSms->setOutId('demo'); $result = $client->execute($sendSms); if ($result->Code === 'OK') { return true; } else { // 错误信息 $error = [ 'isv.ACCOUNT_NOT_EXISTS' => '使用了错误的账户名称或AK', 'isv.ACCOUNT_ABNORMAL' => '账户异常,请确认账号信息', 'isv.MOBILE_NUMBER_ILLEGAL' => '手机号码格式错误', 'isv.SMS_TEMPLATE_ILLEGAL' => '短信模板不存在,或未经审核通过', 'isv.SMS_SIGNATURE_ILLEGAL' => '短信签名不存在,或未经审核通过', 'isv.BUSINESS_LIMIT_CONTROL' => '短信发送频率超限', 'isv.AMOUNT_NOT_ENOUGH' => '当前账户余额不足,请及时充值', 'SignatureDoesNotMatch' => '签名加密错误,请注意accessKeyId和accessKeySecret字符串赋值正确', ]; $tips = '阿里云短信验证码发送失败'; $reason = $error[$result->Code] ?? $result->Message; $response = get_object_vars($result); // 标准类对象转为数组 $record = compact('tips', 'mobile', 'code', 'reason', 'response'); \think\Log::write(json_encode($record, JSON_UNESCAPED_UNICODE), 'sms'); return false; } } ```