123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- <?php
- /**
- * Sms.php UTF-8
- * 短信验证码
- *
- * @date : 2018/4/23 12:29
- *
- * @license 这不是一个自由软件,未经授权不许任何使用和传播。
- * @author : wuyonghong <wyh@huosdk.com>
- * @version : HUOSDK 8.0
- */
- namespace huolib\sms;
- use huolib\constant\CommonConst;
- use huolib\status\MemberStatus;
- use huolib\tool\StrUtils;
- use think\App;
- use think\Cache;
- /**
- * 短信积累
- */
- class Sms {
- protected $options = [];
- protected $tag;
- protected $sms_setting = []; /* 短信设置 */
- protected $key = '';
- protected $sms_content
- = [
- 'send_time' => 0,/* 发送时间戳 */
- 'renew_time' => 0,/* 可以重新发送时间 */
- 'expire_time' => 0,/* 10min钟内过期 */
- 'end_time' => 0,/* 第一次发送后到end_time前发送时间 */
- 'send_cnt' => 0,/* 今日发送次数 */
- 'sms_code' => 0,/* 短信验证码 */
- 'sms_type' => 0,/* 短信发送类型 */
- ];
- protected $max_cnt = 50; /* 单个手机号每日发送最大数量 */
- protected $expire_time = 600; /* 过期时间 */
- protected $end_time = CommonConst::CONST_DAY_SECONDS; /* 结束时间 */
- protected $renew_time = 120; /* 可以重新发送时间 */
- public function __construct() {
- /* 获取短信设置 */
- $_conf_file = GLOBAL_CONF_PATH."extra/sms/setting.php";
- if (file_exists($_conf_file)) {
- $_sms_setting = include $_conf_file;
- foreach ($_sms_setting as $_key => $_val) {
- if (0 != $_val) {
- $this->sms_setting[$_key] = $_val;
- }
- }
- }
- }
- /**
- * 标准返回
- *
- * @param $code
- *
- * @return mixed
- */
- private function getReturnByCode($code) {
- $_rdata['code'] = $code;
- $_rdata['msg'] = MemberStatus::getMsg($code);
- $_rdata['data'] = [];
- return $_rdata;
- }
- /**
- * 发送短信验证码
- *
- * @param $mobile
- * @param $type
- *
- * @return mixed
- */
- public function send($mobile, $type) {
- /* 检查手机号格式是否正确 */
- $_rs = StrUtils::checkPhone($mobile);
- if (false == $_rs) {
- return $this->getReturnByCode(MemberStatus::PHONE_ERROR);
- }
- $_rs = SmsType::checkSmsType($type);
- if (false == $_rs) {
- return $this->getReturnByCode(MemberStatus::CODE_TYPE_ERROR);
- }
- $_is_not_send = $this->isNotSend($mobile);
- if (true !== $_is_not_send) {
- /* 手机短信码已发送 */
- return $this->getReturnByCode(MemberStatus::PHONE_HAS_SEND);
- }
- $_sms_code = $this->genSmsCode();
- $_send_rs = $this->sendExec($mobile, $type, $_sms_code);
- if (MemberStatus::NO_ERROR != $_send_rs) {
- /* 验证码发送失败 */
- return $this->getReturnByCode($_send_rs);
- }
- $_sms_content = $this->get($mobile);
- $_end_time = strtotime(date('Y-m-d')) + $this->end_time;
- if (empty($_sms_content)) {
- $_sms_content = $this->sms_content;
- $_sms_content['end_time'] = $_end_time;
- }
- $_sms_content['send_time'] = time();
- $_sms_content['renew_time'] = $_sms_content['send_time'] + $this->renew_time;
- $_sms_content['expire_time'] = $_sms_content['send_time'] + $this->expire_time;
- $_sms_content['send_cnt']++;
- $_sms_content['sms_code'] = $_sms_code;
- $_sms_content['sms_type'] = $type;
- $this->set($mobile, $_sms_content);
- /* 验证码发送成功 */
- return $this->getReturnByCode(MemberStatus::NO_ERROR);
- }
- /**
- * 校验手机验证码
- *
- * @param $mobile
- * @param $sms_code
- * @param $type
- *
- * @return mixed
- */
- public function check($mobile, $sms_code, $type) {
- // TODO: wuyonghong 2018/4/26 添加校验
- if (APP::$debug) {
- return $this->getReturnByCode(MemberStatus::NO_ERROR);
- }
- /* 检查手机号格式是否正确 */
- $_rs = StrUtils::checkPhone($mobile);
- if (false == $_rs) {
- return $this->getReturnByCode(MemberStatus::PHONE_ERROR);
- }
- $_rs = SmsType::checkSmsType($type);
- if (false == $_rs) {
- return $this->getReturnByCode(MemberStatus::CODE_TYPE_ERROR);
- }
- $_sms_content = $this->get($mobile);
- if (empty($_sms_content) || empty($_sms_content['sms_code'])) {
- /* 查询是否发送过验证码 */
- return $this->getReturnByCode(MemberStatus::CODE_NOT_SEND);
- }
- $_now_time = time();
- if (empty($_sms_content['expire_time']) || ($_sms_content['expire_time'] < $_now_time && !APP::$debug)) {
- /* 查询验证码是否过期 */
- $_sms_content['sms_type'] = '';
- $_sms_content['sms_code'] = '';
- $_sms_content['send_time'] = 0;
- $_sms_content['renew_time'] = 0;
- $_sms_content['expire_time'] = 0;
- $this->set($mobile, $_sms_content);
- return $this->getReturnByCode(MemberStatus::CODE_IS_EXPIRED);
- }
- if ($_sms_content['sms_code'] != $sms_code) {
- /* 验证码错误 */
- return $this->getReturnByCode(MemberStatus::CODE_ERROR);
- }
- if (!APP::$debug) {
- /* 调试模式可以一直验证 */
- /* 验证成功 */
- $_sms_content['sms_type'] = '';
- $_sms_content['sms_code'] = '';
- $_sms_content['send_time'] = 0;
- $_sms_content['renew_time'] = 0;
- $_sms_content['expire_time'] = 0;
- $this->set($mobile, $_sms_content);
- }
- return $this->getReturnByCode(MemberStatus::NO_ERROR);
- }
- /**
- * 生成短信验证码
- *
- * @return string
- */
- private function genSmsCode() {
- $_sms_code = rand(100000, 999999);
- return $_sms_code.'';
- }
- /**
- * 获取Cache key
- *
- * @param string $mobile
- *
- * @return string
- */
- public function getKey($mobile = '') {
- return 'sms_'.$mobile;
- }
- /**
- * 判断短信是否发送
- *
- * @param $mobile
- *
- * @return mixed true 表示未发送 其他 表示已发送
- */
- private function isNotSend($mobile) {
- $_sms_content = $this->get($mobile);
- if (empty($_sms_content)) {
- return true;
- }
- $_now_time = time();
- if ($_sms_content['end_time'] >= $_now_time) {
- /* 超过最后时间,删除所有 */
- $this->clear($mobile);
- return true;
- }
- if ($_sms_content['renew_time'] > $_now_time) {
- /* 未超过限定时间 */
- return $this->getReturnByCode(MemberStatus::PHONE_HAS_SEND);
- }
- if ($_sms_content['send_cnt'] >= $this->max_cnt) {
- /* 每日最多发送次数 */
- return $this->getReturnByCode(MemberStatus::PHONE_SEND_MORE);
- }
- return true;
- }
- /**
- * 获取内容
- *
- * @param $mobile
- *
- * @return mixed
- */
- private function get($mobile) {
- $_key = $this->getKey($mobile);
- return Cache::get($_key);
- }
- /**
- * 设置键值
- *
- * @param $mobile
- * @param $data
- */
- private function set($mobile, $data) {
- $_key = $this->getKey($mobile);
- Cache::set($_key, $data);
- }
- private function clear($mobile) {
- $_key = $this->getKey($mobile);
- Cache::rm($_key);
- }
- /**
- * 执行发送短信验证码
- *
- * @param $mobile
- * @param $type
- * @param $sms_code
- *
- * @return bool
- */
- private function sendExec($mobile, $type, $sms_code) {
- $_rs_code = MemberStatus::NO_ERROR;
- foreach ($this->sms_setting as $_key => $_val) {
- $_class_name = '\\huolib\\sms\\driver\\'.ucwords($_key);
- $_class = new $_class_name();
- $_rs_code = $_class->send($mobile, $type, $sms_code);
- if (MemberStatus::NO_ERROR == $_rs_code) {
- break;
- }
- }
- return $_rs_code;
- }
- /**
- * @return int
- */
- public function getMaxCnt() {
- return $this->max_cnt;
- }
- /**
- * @param int $max_cnt
- */
- public function setMaxCnt($max_cnt) {
- $this->max_cnt = $max_cnt;
- }
- /**
- * @return int
- */
- public function getExpireTime() {
- return $this->expire_time;
- }
- /**
- * @param int $expire_time
- */
- public function setExpireTime($expire_time) {
- $this->expire_time = $expire_time;
- }
- /**
- * @return int
- */
- public function getRenewTime() {
- return $this->renew_time;
- }
- /**
- * @param int $renew_time
- */
- public function setRenewTime($renew_time) {
- $this->renew_time = $renew_time;
- }
- }
|