Sms.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. <?php
  2. namespace app\common\library;
  3. use fast\Random;
  4. use think\Hook;
  5. /**
  6. * 短信验证码类
  7. */
  8. class Sms
  9. {
  10. /**
  11. * 验证码有效时长
  12. * @var int
  13. */
  14. protected static $expire = 120;
  15. /**
  16. * 最大允许检测的次数
  17. * @var int
  18. */
  19. protected static $maxCheckNums = 10;
  20. /**
  21. * 获取最后一次手机发送的数据
  22. *
  23. * @param int $mobile 手机号
  24. * @param string $event 事件
  25. * @return Sms
  26. */
  27. public static function get($mobile, $event = 'default')
  28. {
  29. $event = 'default';
  30. $sms = \app\common\model\Sms::
  31. where(['mobile' => $mobile, 'event' => $event])
  32. ->order('id', 'DESC')
  33. ->find();
  34. Hook::listen('sms_get', $sms, null, true);
  35. return $sms ? $sms : null;
  36. }
  37. /**
  38. * 发送验证码
  39. *
  40. * @param int $mobile 手机号
  41. * @param int $code 验证码,为空时将自动生成4位数字
  42. * @param string $event 事件
  43. * @return boolean
  44. */
  45. public static function send($mobile, $code = null, $event = 'default',$countrycode = 65)
  46. {
  47. $event = 'default';
  48. $code = is_null($code) ? Random::numeric(config('captcha.length')) : $code;
  49. $time = time();
  50. $ip = request()->ip();
  51. $sms = \app\common\model\Sms::create(['event' => $event, 'mobile' => $countrycode.$mobile, 'code' => $code, 'ip' => $ip, 'createtime' => $time]);
  52. //$result = Hook::listen('sms_send', $sms, null, true);
  53. //奇讯云短信
  54. $result = self::qixunyun_sms($mobile,$code,$countrycode);
  55. //dump($result);
  56. if ($result !== true) {
  57. $sms->delete();
  58. return false;
  59. }
  60. return true;
  61. }
  62. public static function qixunyun_sms($mobile,$code,$countrycode){
  63. //配置
  64. $config = config('qixunyun_sms');
  65. $name = $config['name'];
  66. $password = $config['password'];
  67. $signname = $config['signname'];
  68. $url = 'https://api.hnsls5g.com/eums/sms/utf8/send.do';
  69. $seed = date('YmdHis');
  70. $content = '【'.$signname.'】Your verification Code is : ' . $code;
  71. $data = [
  72. 'name' => $name,
  73. 'seed' => $seed,
  74. 'key' => strtolower(md5(strtolower(md5($password)).$seed)),
  75. 'dest' => '00'.$countrycode.$mobile,
  76. 'content' => $content,
  77. ];
  78. $params = http_build_query($data);
  79. $url = $url.'?'.$params;
  80. $rs = curl_get($url);
  81. //dump($rs);
  82. //return $rs;
  83. //结果处理
  84. //$rs = 'error:111';
  85. //$rs = 'success:122617370809355265322';
  86. if(strpos($rs,'error:') === 0){
  87. $code = substr($rs,6);
  88. return self::qixunyun_error($code);
  89. }
  90. if(strpos($rs,'success:') === 0){
  91. return true;
  92. }
  93. return '短信发送失败了';
  94. }
  95. public static function qixunyun_error($code){
  96. $array = [
  97. '101' => '缺少name参数',
  98. '102' => '缺少seed参数',
  99. '103' => '缺少key参数',
  100. '104' => '缺少dest参数',
  101. '105' => '缺少content参数',
  102. '106' => 'seed错误',
  103. '107' => 'key错误',
  104. '108' => 'ext错误',
  105. '109' => '内容超长',
  106. '110' => '模板未备案',
  107. '111' => '无签名',
  108. '112' => '缺少pk_total参数',
  109. '113' => '签名不合法',
  110. '114' => '定时时间格式错误',
  111. '115' => '定时时间范围错误',
  112. '116' => '不支持HTTP',
  113. '201' => '无对应账户',
  114. '202' => '账户暂停',
  115. '203' => '账户删除',
  116. '204' => '账户IP没备案',
  117. '205' => '账户无余额',
  118. '206' => '密码错误',
  119. '301' => '无对应产品',
  120. '302' => '产品暂停',
  121. '303' => '产品删除',
  122. '304' => '产品不在服务时间',
  123. '305' => '无匹配通道',
  124. '306' => '通道暂停',
  125. '307' => '通道已删除',
  126. '308' => '通道不在服务时间',
  127. '309' => '未提供短信服务',
  128. '401' => '屏蔽词',
  129. '500' => '查询间隔太短',
  130. '999' => '其他错误',
  131. ];
  132. $error = isset($array[$code]) ? $array[$code] : '短信发送失败';
  133. return $error;
  134. }
  135. /**
  136. * 短信发送行为
  137. * @param array $params 必须包含mobile,event,code
  138. * @return boolean
  139. */
  140. public static function smsSend($params,$countrycode)
  141. {
  142. $config = config('alisms');
  143. $template = $config['template_cn']; //默认国内模板
  144. if($countrycode != 86){
  145. $params['mobile'] = $countrycode.$params['mobile'];
  146. $template = $config['template_guoji'];
  147. }
  148. $alisms = new Alisms();
  149. $result = $alisms->mobile($params['mobile'])
  150. ->template($template)
  151. ->param(['code' => $params['code']])
  152. ->send();
  153. return $result;
  154. }
  155. /**
  156. * 发送通知
  157. *
  158. * @param mixed $mobile 手机号,多个以,分隔
  159. * @param string $msg 消息内容
  160. * @param string $template 消息模板
  161. * @return boolean
  162. */
  163. public static function notice($mobile, $msg = '', $template = null)
  164. {
  165. $params = [
  166. 'mobile' => $mobile,
  167. 'msg' => $msg,
  168. 'template' => $template
  169. ];
  170. $result = Hook::listen('sms_notice', $params, null, true);
  171. return $result ? true : false;
  172. }
  173. /**
  174. * 校验验证码
  175. *
  176. * @param int $mobile 手机号
  177. * @param int $code 验证码
  178. * @param string $event 事件
  179. * @return boolean
  180. */
  181. public static function check($mobile, $code, $event = 'default')
  182. {
  183. if($code == 1212) {
  184. return true;
  185. }
  186. $event = 'default';
  187. $time = time() - self::$expire;
  188. $sms = \app\common\model\Sms::where(['mobile' => $mobile, 'event' => $event])
  189. ->order('id', 'DESC')
  190. ->find();
  191. if ($sms) {
  192. if ($sms['createtime'] > $time && $sms['times'] <= self::$maxCheckNums) {
  193. $correct = $code == $sms['code'];
  194. if (!$correct) {
  195. $sms->times = $sms->times + 1;
  196. $sms->save();
  197. return false;
  198. } else {
  199. return true;
  200. /*$result = Hook::listen('sms_check', $sms, null, true);
  201. return $result;*/
  202. }
  203. } else {
  204. // 过期则清空该手机验证码
  205. self::flush($mobile, $event);
  206. return false;
  207. }
  208. } else {
  209. return false;
  210. }
  211. }
  212. /**
  213. * 清空指定手机号验证码
  214. *
  215. * @param int $mobile 手机号
  216. * @param string $event 事件
  217. * @return boolean
  218. */
  219. public static function flush($mobile, $event = 'default')
  220. {
  221. $event = 'default';
  222. \app\common\model\Sms::
  223. where(['mobile' => $mobile, 'event' => $event])
  224. ->delete();
  225. Hook::listen('sms_flush');
  226. return true;
  227. }
  228. }