
下面我将详细介绍如何使用ThinkPHP框架实现短信验证注册功能,包括数据库设计、短信发送、验证码验证等完整流程。
1. 数据库设计
首先创建用户表和短信验证码表:
-- 用户表CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `mobile` varchar(20) NOT NULL COMMENT '手机号', `password` varchar(255) NOT NULL COMMENT '密码', `nickname` varchar(50) DEFAULT NULL COMMENT '昵称', `status` tinyint(1) DEFAULT '1' COMMENT '状态(1:正常,0:禁用)', `create_time` int(11) DEFAULT NULL COMMENT '创建时间', `update_time` int(11) DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `mobile` (`mobile`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';-- 短信验证码表CREATE TABLE `sms_code` ( `id` int(11) NOT NULL AUTO_INCREMENT, `mobile` varchar(20) NOT NULL COMMENT '手机号', `code` varchar(10) NOT NULL COMMENT '验证码', `create_time` int(11) NOT NULL COMMENT '创建时间', `expire_time` int(11) NOT NULL COMMENT '过期时间', `ip` varchar(50) DEFAULT NULL COMMENT 'IP地址', `status` tinyint(1) DEFAULT '0' COMMENT '状态(0:未使用,1:已使用)', PRIMARY KEY (`id`), KEY `mobile` (`mobile`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='短信验证码表';
2. 创建模型
创建用户模型和短信验证码模型:
// application/index/model/User.phpnamespace app\index\model;use think\Model;class User extends Model{
// 设置当前模型对应的完整数据表名称
protected $table = 'user';
// 自动时间戳
protected $autoWriteTimestamp = true;
// 密码加密
public function setPasswordAttr($value)
{
return password_hash($value, PASSWORD_DEFAULT);
}}// application/index/model/SmsCode.phpnamespace app\index\model;use think\Model;class SmsCode extends Model{
// 设置当前模型对应的完整数据表名称
protected $table = 'sms_code';
// 自动时间戳
protected $autoWriteTimestamp = 'create_time';}3. 短信服务类
创建短信服务类,这里以阿里云短信为例:
// application/common/service/SmsService.phpnamespace app\common\service;use think\facade\Config;class SmsService{
// 发送短信验证码
public static function sendCode($mobile, $code)
{
// 这里替换为你的阿里云短信配置
$config = Config::get('aliyun_sms');
$params = [
'PhoneNumbers' => $mobile,
'SignName' => $config['sign_name'],
'TemplateCode' => $config['template_code'],
'TemplateParam' => json_encode(['code' => $code])
];
// 调用阿里云短信接口
try {
$result = self::sendSms($params);
return $result;
} catch (\Exception $e) {
return false;
}
}
// 阿里云短信发送方法
private static function sendSms($params)
{
// 这里实现阿里云短信发送逻辑
// 实际项目中应该使用阿里云官方SDK
// 模拟发送成功
return true;
}}4. 控制器实现
创建注册控制器:
// application/index/controller/Register.phpnamespace app\index\controller;use think\Controller;use think\facade\Config;use think\facade\Request;use app\index\model\User;use app\index\model\SmsCode;use app\common\service\SmsService;class Register extends Controller{
// 发送短信验证码
public function sendCode()
{
$mobile = Request::param('mobile');
// 验证手机号格式
if (!preg_match('/^1[3-9]\d{9}$/', $mobile)) {
return json(['code' => 0, 'msg' => '手机号格式不正确']);
}
// 检查手机号是否已注册
if (User::where('mobile', $mobile)->find()) {
return json(['code' => 0, 'msg' => '该手机号已注册']);
}
// 生成验证码
$code = mt_rand(100000, 999999);
// 保存验证码到数据库
$smsData = [
'mobile' => $mobile,
'code' => $code,
'expire_time' => time() + 300, // 5分钟后过期
'ip' => Request::ip()
];
SmsCode::create($smsData);
// 发送短信
if (SmsService::sendCode($mobile, $code)) {
return json(['code' => 1, 'msg' => '验证码发送成功']);
} else {
return json(['code' => 0, 'msg' => '验证码发送失败']);
}
}
// 用户注册
public function doRegister()
{
$data = Request::param();
// 验证数据
$validate = new \app\index\validate\Register;
if (!$validate->check($data)) {
return json(['code' => 0, 'msg' => $validate->getError()]);
}
// 验证短信验证码
$smsCode = SmsCode::where([
'mobile' => $data['mobile'],
'code' => $data['code'],
'status' => 0
])->order('id', 'desc')->find();
if (!$smsCode) {
return json(['code' => 0, 'msg' => '验证码错误']);
}
if ($smsCode->expire_time < time()) {
return json(['code' => 0, 'msg' => '验证码已过期']);
}
// 创建用户
$userData = [
'mobile' => $data['mobile'],
'password' => $data['password'],
'nickname' => '用户_' . substr($data['mobile'], -4)
];
$user = User::create($userData);
if ($user) {
// 标记验证码为已使用
$smsCode->status = 1;
$smsCode->save();
return json(['code' => 1, 'msg' => '注册成功']);
} else {
return json(['code' => 0, 'msg' => '注册失败']);
}
}}5. 验证器
创建注册验证器:
// application/index/validate/Register.phpnamespace app\index\validate;use think\Validate;class Register extends Validate{
protected $rule = [
'mobile' => 'require|mobile',
'password' => 'require|length:6,20',
'code' => 'require|length:6',
];
protected $message = [
'mobile.require' => '手机号不能为空',
'mobile.mobile' => '手机号格式不正确',
'password.require' => '密码不能为空',
'password.length' => '密码长度6-20位',
'code.require' => '验证码不能为空',
'code.length' => '验证码长度6位',
];
// 自定义手机号验证规则
protected function mobile($value)
{
return preg_match('/^1[3-9]\d{9}$/', $value) ? true : false;
}}6. 前端页面
创建注册页面(使用jQuery):
<!-- application/index/view/register/index.html --><!DOCTYPE html><html><head>
<meta charset="utf-8">
<title>用户注册</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script></head><body>
<h1>用户注册</h1>
<form id="registerForm">
<div>
<label>手机号:</label>
<input type="text" name="mobile" placeholder="请输入手机号">
<button type="button" id="sendCodeBtn">获取验证码</button>
</div>
<div>
<label>验证码:</label>
<input type="text" name="code" placeholder="请输入验证码">
</div>
<div>
<label>密码:</label>
<input type="password" name="password" placeholder="请输入密码">
</div>
<div>
<button type="submit">注册</button>
</div>
</form>
<script>
$(function() {
// 发送验证码
$('#sendCodeBtn').click(function() {
var mobile = $('input[name="mobile"]').val();
if (!/^1[3-9]\d{9}$/.test(mobile)) {
alert('手机号格式不正确');
return;
}
$(this).attr('disabled', true);
$.post('{:url("register/sendCode")}', {mobile: mobile}, function(res) {
if (res.code == 1) {
alert('验证码发送成功');
// 倒计时
var countdown = 60;
var timer = setInterval(function() {
countdown--;
$('#sendCodeBtn').text(countdown + '秒后重新获取');
if (countdown <= 0) {
clearInterval(timer);
$('#sendCodeBtn').text('获取验证码').attr('disabled', false);
}
}, 1000);
} else {
alert(res.msg);
$('#sendCodeBtn').attr('disabled', false);
}
}, 'json');
});
// 注册提交
$('#registerForm').submit(function(e) {
e.preventDefault();
var formData = $(this).serialize();
$.post('{:url("register/doRegister")}', formData, function(res) {
if (res.code == 1) {
alert('注册成功');
window.location.href = '{:url("index/index")}';
} else {
alert(res.msg);
}
}, 'json');
});
});
</script></body></html>7. 路由配置
在路由配置文件中添加路由:
// route/route.phpuse think\facade\Route;Route::get('register', 'index/register/index');Route::post('register/sendCode', 'index/register/sendCode');Route::post('register/doRegister', 'index/register/doRegister');8. 配置阿里云短信
在配置文件中添加阿里云短信配置:
// config/aliyun_sms.phpreturn [ 'access_key_id' => 'your_access_key_id', 'access_secret' => 'your_access_secret', 'sign_name' => 'your_sign_name', 'template_code' => 'your_template_code', 'region_id' => 'cn-hangzhou'];
9. 完整流程说明
用户访问注册页面,输入手机号
点击获取验证码按钮,前端发送AJAX请求到
/register/sendCode后端验证手机号格式和是否已注册
生成6位随机验证码并保存到数据库
调用阿里云短信接口发送验证码
用户输入验证码和密码提交注册
后端验证验证码是否正确和是否过期
验证通过后创建用户账号
标记验证码为已使用状态
返回注册成功信息
10. 安全注意事项
验证码有效期:设置合理的有效期(通常5-10分钟)
验证码使用限制:每个验证码只能使用一次
IP限制:限制同一IP的发送频率
手机号限制:限制同一手机号的发送频率
密码加密:使用password_hash加密存储密码
防XSS攻击:对用户输入进行过滤
防CSRF攻击:添加CSRF令牌验证
以上就是一个完整的ThinkPHP短信验证注册功能的实现方案,你可以根据实际需求进行调整和扩展。
希望以上内容对你有所帮助!如果还有其他问题,请随时提问。 各类知识收集 拥有多年CMS企业建站经验,对 iCMS, LeCMS, ClassCMS, Fastadmin, PbootCMS, PHPCMS, 易优CMS, YzmCMS, 讯睿CMS, 极致CMS, Wordpress, HkCMS, YznCMS, WellCMS, ThinkCMF, 等各类cms的相互转化,程序开发,网站制作,bug修复,程序杀毒,插件定制都可以提供最佳解决方案。


