1. 程式人生 > >php+mysql實現簡訊驗證碼功能

php+mysql實現簡訊驗證碼功能

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;
    }

}