Sms.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <?php
  2. /**
  3. * 短信服务
  4. * @author wesmiler
  5. */
  6. namespace app\weixin\service;
  7. use AlibabaCloud\Client\AlibabaCloud;
  8. use GuzzleHttp\Exception\ClientException;
  9. use GuzzleHttp\Exception\SeekException;
  10. class Sms
  11. {
  12. /**
  13. * 发生短信验证码
  14. * @param $mobile 手机号码
  15. * @param $params 短信参数:tpName-模板名称标识,code-短信验证码,expire-有效期/s
  16. * @param string $scene 场景标识:默认code
  17. * @return array|bool
  18. */
  19. public static function sendCode($mobile, $params, $scene = 'code')
  20. {
  21. if(empty($mobile)){
  22. return 2012;
  23. }
  24. // 参数配置
  25. $smsConfig = cmf_get_option('sms_config');
  26. $tpName = isset($params['tpName']) ? $params['tpName'] : ''; // 短信模板名称
  27. $code = isset($params['code']) ? trim($params['code']) : ''; // 验证码
  28. $codeLength = isset($smsConfig['code_length']) ? intval($smsConfig['code_length']) : 0;
  29. $codeLength = $codeLength>=4? $codeLength-1 : 5;
  30. $numMin = pow(10,$codeLength);
  31. $numMax = pow(10,$codeLength+1)-1;
  32. $code = $code? $code : rand($numMin,$numMax);
  33. $expire = isset($params['expire']) && $params['expire']? intval($params['expire']) : 300; // 有效期
  34. $openSms = isset($smsConfig['status']) ? $smsConfig['status'] : true; // 短信功能是否开启
  35. $signName = isset($smsConfig['sign_name']) ? $smsConfig['sign_name'] : '';
  36. $accessKey = isset($smsConfig['access_key']) ? $smsConfig['access_key'] : '';
  37. $accessSecret = isset($smsConfig['access_secret']) ? $smsConfig['access_secret'] : '';
  38. $regionId = isset($smsConfig['sms_region']) ? $smsConfig['sms_region'] : 'cn-hangzhou';
  39. $templateId = isset($smsConfig[$tpName . '_template_id']) ? $smsConfig[$tpName . '_template_id'] : '';
  40. $jsonData = json_encode(['code' => $code], 256);
  41. if(!$openSms){
  42. PRedis::set('sms:error_'.$scene.':'.$mobile, ['config'=> $smsConfig,'params'=> $params], 600);
  43. return 2018;
  44. }
  45. if(empty($accessSecret) || empty($accessSecret) || empty($templateId)){
  46. PRedis::set('sms:error_'.$scene.':'.$mobile, ['config'=> $smsConfig,'params'=> $params], 600);
  47. return 2014;
  48. }
  49. if(empty($signName) || empty($tpName) || empty($code)){
  50. PRedis::set('sms:error_'.$scene.':'.$mobile, ['config'=> $smsConfig,'params'=> $params], 600);
  51. return 2015;
  52. }
  53. if(PRedis::get('sms:lock_'.$scene.':'.$mobile)){
  54. return 2021;
  55. }
  56. // 初始化参数
  57. AlibabaCloud::accessKeyClient($accessKey, $accessSecret)
  58. ->regionId($regionId ? $regionId : 'cn-hangzhou')
  59. ->asDefaultClient();
  60. // 处理调用
  61. try {
  62. $params = [
  63. 'RegionId' => $regionId? $regionId : 'cn-hangzhou',
  64. 'PhoneNumbers' => $mobile,
  65. 'SignName' => $signName,
  66. 'TemplateCode' => $templateId,
  67. 'TemplateParam' => $jsonData,
  68. ];
  69. $result = AlibabaCloud::rpc()
  70. ->product('Dysmsapi')
  71. ->version('2017-05-25')
  72. ->action('SendSms')
  73. ->method('POST')
  74. ->options(['query' => $params])
  75. ->request();
  76. $result = $result? $result->toArray() : [];
  77. PRedis::set('sms:result_'.$scene.':'.$mobile, $result, 600);
  78. if ($result && $result['Code'] == "OK"){
  79. // 写缓存
  80. $codeData = ['code'=> $code, 'params'=> $params, 'date'=> date('Y-m-d H:i:s')];
  81. PRedis::set('sms:scene_'.$scene.':'.$mobile, $codeData, $expire);
  82. PRedis::set('sms:lock_'.$scene.':'.$mobile, $code, 10);
  83. return $codeData;
  84. }else{
  85. return isset($result['Message']) && $result['Message']? $result['Message'] : 2017;
  86. }
  87. } catch (ClientException $exception) {
  88. PRedis::set('sms:error_'.$scene.':'.$mobile, $exception->getMessage(), 600);
  89. return 2017;
  90. } catch (SeekException $exception) {
  91. PRedis::set('sms:error_'.$scene.':'.$mobile, $exception->getMessage(), 600);
  92. return 2017;
  93. }
  94. }
  95. /**
  96. * 验证短信验证码
  97. * @param $mobile 手机号码
  98. * @param $code 当前验证码
  99. * @param string $scene 场景:code-默认
  100. * @return bool|int
  101. */
  102. public static function checkCode($mobile, $code, $scene='code'){
  103. $codeData = PRedis::get('sms:scene_'.$scene.':'.$mobile);
  104. $sendCode = isset($codeData['code'])? $codeData['code'] : '';
  105. if(empty($codeData)){
  106. return 2019;
  107. }
  108. if($sendCode == $code){
  109. PRedis::del('sms:scene_'.$scene.':'.$mobile);
  110. return true;
  111. }
  112. return 2020;
  113. }
  114. }