微博项目_登录注册功能

登录注册功能在一个项目中是很常见的,所以我希望将该微博项目中用到的方法和思路归纳一下,方便自己日后去进行调用。
因为使用的ThinkPHP框架,所以功能的实现是建立在该框架之上的,有关TP的部分在这里不多做说明,默认按照它的架构去进行布局。

注册功能

因为登录注册功能涉及到一些表单的提交和处理,在这里使用了一个基于jQuery的Validate插件,该插件为表单提供了强大的验证功能,能够让客户端表单验证变得更加简单。

注册页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!--/practice/Home/View/Login/register.html-->
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>用户注册</title>
<script type="text/javascript" src="__PUBLIC__/JS/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="__PUBLIC__/JS/jquery-validate.js"></script>
<script type="text/javascript" src="__PUBLIC__/JS/register.js"></script>
<script type="text/javascript">
var checkAccount = "{:U('checkAccount')}";
var checkUname = "{:U('checkUname')}";
</script>
</head>
<body>
<form action="{:U('runRegis')}" method="post" name="register">
<fieldset>
<legend>用户注册</legend>
<p>
<label for="account">登录账户:</label>
<input type="text" name="account" id="account" />
</p>
<p>
<label for="pwd">登录密码:</label>
<input type="password" name="pwd" id="pwd" />
</p>
<p>
<label for="pwded">确认密码:</label>
<input type="password" name="pwded" id="pwded" />
</p>
<p>
<label for="uname">昵称:</label>
<input type="text" name="uname" id="uname" />
</p>
<p>
<input type="submit" value="马上注册" id="regis" />
</p>
</fieldset>
</form>
</body>
</html>

查漏补缺:

  1. 引入的js文件,jQuery应放置于第一个,Validate插件是基于jQuery的,所以应放于其后,根据TP框架的布局,js文件均放置于主目录下Public/Js文件夹下。
  2. 脚本中添加的两个变量checkAccount和checkUname是用于js异步验证时所提交的后台处理地址。
  3. 提交表单时涉及到的几个标签及属性,要熟练掌握其用法。
  • action属性用于规定当提交表单时向何处发送表单数据
  • U方法是TP框架中的一个函数,用于URL的动态生成,能够动态地根据当前的URL设置生成对应的URL地址

Js处理脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/* /practice/Public/Js/register.js */
$(function() {
//jQuery Validate 表单验证

/**
* 添加自定义验证方法
* 以字母开头,5-17位 字母、数字、下划线'_'
*/
jQuery.validator.addMethod("user",function(value,element) {
//正则表达式
var tel = /^[a-zA-Z][\w]{4,16}$/;
return this.optional(element) || (tel.test(value));
},"以字母开头,5-17位 字母、数字、下划线'_'");

$('form[name=register]').validate({
errorElement : 'span', //用什么标签标记错误
success : function(label) {
label.addClass('success');
},
rules : {
account : {
required : true, //必须输入的字段
user : true,
//异步验证
remote : {
url : checkAccount, //后台处理地址
type : 'post', //数据发送方式
dataType : 'json', //接收数据格式
data : { //要传递的数据
account : function() {
return $('#account').val();
}
}
}
},
pwd : {
required : true,
user : true
},
pwded : {
required : true,
equalTo : "#pwd" //输入值必须和pwd相同
},
uname : {
required : true,
rangelength : [2,10], //输入长度必须介于2-10之间的字符串
remote : {
url : checkUname,
type : 'post',
dataType : 'json',
data : {
uname : function () {
return $('#uname').val();
}
}
}
}
},
messages : {
account : {
required : '账号不能为空',
remote : '账号已存在'
},
pwd : {
required : '密码不能为空'
},
pwded : {
required : '请确认密码',
equalTo : '两次密码不一致'
},
uname : {
required : '请填写您的昵称',
rangelength : '昵称必须介于2-10个字符串之间',
remote : '昵称已存在'
}
}
});
});

查漏补缺:

Js处理脚本中主要涉及到的就是Validate插件的使用,以下是该插件中常用的一些验证方法。

验证规则 描述
required:true 必须输入的字段
remote:”check.php” 使用ajax方法调用check.php异步验证输入值
equalTo:”#field” 输入值必须和field相同
rangelength:[5,10] 输入长度必须介于5和10之间的字符串
maxlength:5 输入长度最多为5的字符串(汉字算一个字符)
minlength:10 输入长度最小为10的字符串(汉字算一个字符)
email:true 必须输入正确格式的电子邮件
url:true 必须输入正确格式的网址
date:true 必须输入正确格式的日期
number:true 必须输入正确格式的数字

创建用户关联模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* /practice/Home/Model/UserModel.class.php */
<?php
namespace Home\Model;
use Think\Model\RelationModel;
//用户表与用户信息表关联模型
class UserModel extends RelationModel {
//定义用户表与用户信息表关联关系属性
protected $_link = array(
'userinfo' =>array(
'mapping_type' =>self::HAS_ONE, //HAS_ONE表示一对一关联
'class_name' =>'userinfo', //要关联的模型类名
'foreign_key' =>'uid' //关联的外键名称
)
);
//自动插入的方法
public function insert($data=NULL) {
$data = is_null($data) ? $_POST : $data;
return $this->relation(true)->data($data)->add();
}
}
?>

需要创建该关联模型的原因在于根据上一节对于数据库的建模,我们可以看出注册页面提交表单的内容需要插入到两张不同的数据表中(用户表和用户信息表),所以可以使用TP框架中的关联模型将两张表关联起来,从而实现一并插入的效果。

后端php业务处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/* /practice/Home/Controller/LoginController.class.php */
<?php
namespace Home\Controller;
use Think\Controller;

class LoginController extends Controller {
//注册页面
public function register() {
$this->display();
}
//注册表单处理
public function runRegis() {
if (!IS_POST) {
E('页面不存在');
}

if($_POST['pwd'] != $_POST['pwded']) {
$this->error('两次密码不一致');
}

//接收post数据
$data = array(
'account' => I('post.account'),
'password' => I('post.pwd','','md5'),
'registime' => time(),
'userinfo' => array(
'username' => I('post.uname')
)
);
$id = D('User')->insert($data); //insert方法定义在关联模型中
if ($id) {
session('uid',$id);
redirect(__APP__,3,'注册成功,正在跳转中...');
} else {
$this->error('注册失败,请重试');
}
}
//异步验证账号是否存在
public function checkAccount() {
if (!IS_AJAX) {
E('页面不存在');
}
$account = I('post.account');
$where = array('account' => $account);

//Js异步验证时,验证地址端只能返回'false'和'true'
if (M('user')->where($where)->getField('id')) {
echo 'false';
} else {
echo 'true';
}
}
//异步验证昵称是否存在
public function checkUname() {
if (!IS_AJAX) {
E('页面不存在');
}
$uname = I('post.uname');
$where = array('username' => $uname);

if (M('userinfo')->where($where)->getField('id')) {
echo 'false';
} else {
echo 'true';
}
}
}
?>

登录功能

登录页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!--/practice/Home/View/Login/login.html-->
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>用户登录</title>
<script type="text/javascript" src="__PUBLIC__/JS/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="__PUBLIC__/JS/jquery-validate.js"></script>
<script type="text/javascript" src="__PUBLIC__/JS/login.js"></script>
</head>
<body>
<form action="{:U('runLogin')}" method="post" name="login">
<fieldset>
<legend>用户登录</legend>
<p>
<label>登录账户:</label>
<input type="text" name="account" />
</p>
<p>
<label>密码:</label>
<input type="password" name="pwd" />
</p>
<p>
<input type="submit" value="马上登录" />
</p>
</fieldset>
</form>
</body>
</html>

Js处理脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/* /practice/Public/Js/login.js */
$(function() {
jQuery.validator.addMethod("user",function(value,element) {
var tel = /^[a-zA-Z][\w]{4,16}/;
return this.optional(element) || (tel.test(value));
},"以字母开头,5-17位 字母、数字、下划线'_'");

$('form[name=login]').validate({
success : function(label) {
label.addClass('success');
},
rules : {
account : {
required : true,
user : true
},
pwd : {
required : true,
user : true
}
},
messages : {
account : {
required : '账号不能为空'
},
pwd : {
required : '密码不能为空'
}
}
});
});

后端php业务处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/* /practice/Home/Controller/LoginController.class.php */
//登录页面
public function login() {
$this->display();
}
//登录表单处理
public function runLogin() {
if (!IS_POST) {
E('页面不存在');
}
//获取表单内容
$account = I('post.account');
$pwd = I('post.pwd','','md5');

$where = array('account' => $account);
$user = M('user')->where($where)->find();

if (empty($user) || $user['password'] != $pwd) {
$this->error('用户名或者密码不正确');
}

//登录成功,写入session并且跳转到首页
session('uid',$user['id']);
redirect(__APP__,3,'登录成功,正在为您跳转...');
}
-------------The End-------------