🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 注册 User/reg ![2015-06-23/5588acf96a306](http://box.kancloud.cn/2015-06-23_5588acf96a306.png) 注册页的地址是 user/reg。 然后模板就是一个表单 ~~~ <extend name="Index/base" /> <block name="header"></block> <block name="main"> <form class="form-signin" action="{:U('/user/reg')}" method="post"> <h2 class="form-signin-heading">注册</h2> <label for="inputNickname" class="sr-only">用户名</label> <input type="text" id="inputNickname" class="form-control hide-data" placeholder="用户名" required="" autofocus="" name="nickname"> <label for="inputPassword" class="sr-only">密码</label> <input type="password" id="inputPassword" class="form-control hide-data" placeholder="密码" required="" name="pwd"> <button class="btn btn-lg btn-primary ajax-post" type="submit" target-form="form-signin">注册</button> <a href="{:U('/user/login')}" class="btn btn-text">有账号了?点我去登录</a> </form> </block> <block name="sidebar"></block> ~~~ 至于提交表单的ajax,前面已经说过了,common.js里 ajax-post 由于注册和登录逻辑里面有特殊session处理,干脆就没有用rest。rest预留着给后台这种只可能批量添加用户数据,而不需要登录逻辑处理的使用。 //注册 ~~~ public function reg(){ if(IS_POST){ //注册用户 $Member = D('Member'); $nickname = I('post.nickname'); $pwd = I('post.pwd'); $data = $Member->create(array('nickname'=>$nickname, 'pwd'=>$pwd)); if($data){ $Member->startTrans(); if($Member->add()){ if($Member->login($uid, $nickname)){ $Member->commit(); $this->success('注册成功',U('/user/login')); } else { $Member->rollback(); $this->error($Member->getError()); } }else{ $Member->rollback(); $this->error($Member->getError()); } }else{ $this->error($Member->getError()); } } else { //显示注册表单 $this->display(); } } ~~~ 注意的几点: 1. 一个方法里通过IS_POST判断是否是提交数据还是页面显示 2. 使用了事务(数据表必须是支持事务的数据引擎,mysql的是innodb) 3. 插入数据前用模型验证 4. 注册完毕后自动登录(可以选择不自动登录) ## 注册验证和登录 ~~~ protected $_validate = array( array('nickname','','帐号名称已经存在!',0,'unique',self::MODEL_INSERT), // 在新增的时候验证name字段是否唯一 ); protected $_auto = array ( array('status','1'), // 新增的时候把status字段设置为1 array('settings', '{}'), array('pwd','password',1,'function') , // 对password字段在新增的时候使password函数处理 array('create_at','datetime',self::MODEL_INSERT,'function'), // 对create_at字段在更新的时候写入当前时间戳 array('update_at','datetime',self::MODEL_BOTH,'function'), // 对create_time字段在更新的时候写入当前时间戳 ); ~~~ 自动验证和自动完成: 注册时需要验证账号是否被注册过 完成里序列化字段setting的初始化。密码字段pwd的加密处理。以及时间字段的自动完成。 PS:自动完成和自动验证里的时间参数最好用self::MODEL_INSERT 和self::MODEL_BOTH 及self::MODEL_UPDATE 这几个类静态常量,这样不用在0、1、2中记混了。 # 登录 User/login ![2015-06-23/5588c0ac83775](http://box.kancloud.cn/2015-06-23_5588c0ac83775.png) ~~~ public function login(){ if(IS_POST){ //登录验证 $Member = D('Member'); $nickname = I('post.nickname'); $pwd = I('post.pwd'); $uid = $Member->checkLogin($nickname, $pwd); if(0 < $uid){ //登录用户 if($Member->login($uid, $nickname)){ $this->success('登录成功!',U('/mine')); } else { $this->error($Member->getError()); } } else { //登录失败 switch($uid) { case -1: $error = '用户不存在或被禁用!'; break; //系统级别禁用 case -2: $error = '密码错误!'; break; default: $error = '未知错误!'; break; // 0-接口参数错误(调试阶段使用) } $this->error($error); } } else { //显示登录表单 $this->display(); } } ~~~ 登录逻辑也很简单,我们直接看POST部分,checkLogin用于检测用户是否存在以及密码是否对。正确后然后执行Mmember模型的login方法并跳转个人空间。 MemberModel里的checkLogin ~~~ public function checkLogin($nickname, $pwd){ $member = $this->where("nickname = '{$nickname}'")->find(); if($member){ if(password($pwd) == $member['pwd']){ return $member['id']; }else{ return -2; } }else{ return -1; } } ~~~ Member里的login方法 ~~~ public function login($uid, $nickname){ $array = array( 'uid' =>$uid, 'nickname'=>$nickname ); try { session('user', $array); return true; } catch (Exception $e) { $this->error = '未知错误'; return false; } } ~~~ 其实登录就是保存一个session到服务器里,然后用到登录的地方用于获取用户id和账号。 密码相关函数: ~~~ //密码加密 function password($password){ $md5str=md5($password); $salt=get_password_salt($md5str); return hash('sha256',$md5str.$salt); } function get_password_salt($md5str,$d=1001){ $crc32_value = floatval(sprintf("%u", crc32($md5str))); $crc32_value = ($crc32_value > PHP_INT_MAX) ? (($crc32_value - PHP_INT_MAX ) % $d + PHP_INT_MAX % $d) % $d : $crc32_value % $d; return $crc32_value; } ~~~ 高级应用: - session 设置前缀和过期时间 - cookie 自动登录 - [session存入数据库持久化](http://www.jb51.net/article/52557.htm)