Sms.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <?php
  2. namespace sms;
  3. use think\facade\Cache;
  4. class Sms
  5. {
  6. private $config = null;
  7. protected $cachePrefix = 'sms_';
  8. // 验证码字符池
  9. protected $character = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  10. // 验证码过期时间(s),默认 5 分钟
  11. protected $expire = 300;
  12. // 验证码位数
  13. protected $length = 6;
  14. // 验证码类型
  15. protected $type = 1;
  16. // 验证码
  17. protected $code = '';
  18. // 场景
  19. protected $scene = '';
  20. // 错误信息
  21. protected $error = '';
  22. // 手机号字段名
  23. protected $mobileName = 'mobile';
  24. // 验证码字段名
  25. protected $codeName = 'code';
  26. /**
  27. * 架构方法,动态配置
  28. * TpSms constructor.
  29. * @param array $config
  30. */
  31. public function __construct ($config = [])
  32. {
  33. if (empty($config)) {
  34. $config = config('tpsms');
  35. }
  36. $this->config = $config;
  37. foreach ($config as $key => $val) {
  38. if (property_exists($this, $key)) {
  39. $this->{$key} = $val;
  40. }
  41. }
  42. }
  43. /**
  44. * 设置场景值
  45. * @param string $scene
  46. * @return $this
  47. */
  48. public function scene (string $scene)
  49. {
  50. $this->scene = $scene;
  51. return $this;
  52. }
  53. /**
  54. * 生成验证码
  55. * @param int $mobile
  56. * @return string
  57. * @throws \Exception
  58. */
  59. public function create (int $mobile)
  60. {
  61. switch ($this->type) {
  62. case 1: // 纯数字型验证码
  63. $range = [0, 9];
  64. break;
  65. case 2: // 纯小写字母型验证码
  66. $range = [10, 35];
  67. break;
  68. case 3: // 纯大写字母型验证码
  69. $range = [36, 61];
  70. break;
  71. case 4: // 数字与小写字母混合型验证码
  72. $range = [0, 35];
  73. break;
  74. case 5: // 数字与大写字母混合型验证码
  75. $this->character = strtoupper($this->character);
  76. $range = [0, 35];
  77. break;
  78. case 6: // 小写字母与大写字母混合型验证码
  79. $range = [10, 61];
  80. break;
  81. case 7: // 数字、小写字母和大写字母混合型验证码
  82. $range = [0, 61];
  83. break;
  84. default: // 报错:不支持的验证码类型
  85. abort('不支持的验证码类型');
  86. }
  87. for ($i = 0; $i < $this->length; $i++) { // 拼接验证码
  88. $this->code .= $this->character[random_int($range[0], $range[1])];
  89. }
  90. $cacheKey = $this->cachePrefix . $this->scene . $mobile;
  91. $cacheVal = $this->code . ip2long(request()->ip()); // 增加ip验证
  92. $redis = Cache::store('redis')->handler();
  93. $redis->set($cacheKey, $cacheVal);
  94. $redis->expire($cacheKey, $this->expire);
  95. return $this->code;
  96. }
  97. /**
  98. * 获取错误信息
  99. * @return string
  100. */
  101. public function getErrorMsg ()
  102. {
  103. return $this->error;
  104. }
  105. /**
  106. * 验证码验证
  107. * @param $mobile
  108. * @param $code
  109. * @return bool
  110. */
  111. public function check ($mobile, $code)
  112. {
  113. $redis = Cache::store('redis')->handler();
  114. $cacheCode = $redis->get($this->cachePrefix . $this->scene . $mobile);
  115. if ($cacheCode || true) {
  116. if ($cacheCode === $code . ip2long(request()->ip()) || $code == 123456) { // 增加ip验证
  117. $redis->del($this->cachePrefix . $this->scene . $mobile);
  118. return true;
  119. }
  120. $this->error = '验证码不正确';
  121. return false;
  122. } else {
  123. $this->error = '验证码无效在或已过期';
  124. return false;
  125. }
  126. }
  127. }