class Sms {
const EXPIRE_SEC = 300; // 過期時間間隔 5分鐘
const RESEND_SEC = 60; // 重發時間間隔
const ONE_DAY_FREQ = 10; // 每日向同一個手機號發短信的次數
public $error = '';
protected $sms_status = array(
"0" => "短信發送成功",
"-1" => "參數不全",
);
/**
* 向指定手機號發送驗證碼
* @param $phone
* @param $imei
* @return bool
*/
public function sendVerifyCode($phone, $sendtype) {
if (!$this->isMobile($phone)) {
$this->error = '這個手機號很奇葩哦,請正確輸入後重試';
return false;
}
$where['phone'] = $phone;
$start = strtotime(date('Y-m-d 00:00:00'));
$where['createtime'] = ['between', [$start, time()]];
$list = SmsModel::getAll('id, expiretime, createtime', $where, 'id desc');
// 驗證碼重發限制
if($list) {
$data = $list[0];
if ((time() > $data['createtime']) && (time() < ($data['createtime'] + self::RESEND_SEC))) {
$this->error = '短信已在1分鐘內發出,請耐心等待';
return false;
}
}
$imeiCnt = count($list);
if ($imeiCnt >= self::ONE_DAY_FREQ) {
$this->error = '當日已超過驗證碼發送設備限制';
return false;
}
// 獲取驗證碼
$vc = strval(rand(1000, 9999));
$expire_min = self::EXPIRE_SEC / 60;
switch ($sendtype) {
case '1':
$content = '【xxxx】你的註冊驗證碼是:'.$vc.',在'.$expire_min.'分鐘內有效。請勿告知他人。';
break;
case '2':
$content = '【xxxx】你的找回密碼驗證碼是:'.$vc.',在'.$expire_min.'分鐘內有效。請勿告知他人。';
break;
default:
$this->error = '發送驗證碼類型錯誤';
return false;
break;
}
$result = $this->send($phone, $content);
if ($result != '') {
if($result == 0) {
$save_res = $this->saveSmsInfo($phone, $content, $vc);
if($save_res) {
return true;
}
}else{
$this->error = $this->sms_status[$result];
return false;
}
}
$this->error = '發送失敗';
return false;
}
/**
* 向指定手機號發送短信
* @param $phone
* @param $content
* @return bool
*/
public function send($phone, $content) {
// TODO 調用具體服務商API
}
/**
* [saveSmsInfo 保存短信信息]
* @param [type] $phone [手機號]
* @param [type] $content [內容]
* @param [type] $verifycode [驗證碼]
* @return [type] [bool]
*/
private function saveSmsInfo($phone, $content, $verifycode) {
$data = [
'phone' => $phone,
'content' => $content,
'verifycode' => $verifycode,
'ip' => request()->ip(),
'createtime' => time(),
'expiretime' => time() + self::EXPIRE_SEC,
];
return SmsModel::addData($data);
}
/**
* 判斷是否爲合法手機號
* @param $phone
* @return bool
*/
private function isMobile($phone) {
if (preg_match('/^1\d{10}$/', $phone)) return true;
return false;
}
/**
* 驗證短信驗證碼
* @param $phone
* @param $vc
* @return bool
*/
public function checkVerifyCode($phone, $verifycode) {
$vcData = SmsModel::where(['phone' => $phone])->field('verifycode, expiretime')->order('id desc')->find();
if ($vcData && $vcData->verifycode == $verifycode) {
if($vcData->expiretime >= time()) {
return true;
}
}
return false;
}
}