thinkphp实现注册登录功能

使用最新的thinkphp3.2.3版本,需要注意命名空间的使用。 均为后台验证,前台ajax验证未做处理。后续加上。。。 登录时,更新用户数据,登录ip和登录时间,以及登录次数+1,此实现方便不知是否合适,待验证。 源码地址:https://github.com/grh0812/thinkphp-login-register

创建数据库 :

代码语言:javascript
复制
/*
Navicat MySQL Data Transfer

Source Server : 本地连接
Source Server Version : 50617
Source Host : localhost:3306
Source Database : crm

Target Server Type : MYSQL
Target Server Version : 50617
File Encoding : 65001

Date: 2015-06-29 23:55:28
*/

SET FOREIGN_KEY_CHECKS=0;


-- Table structure for think_users


DROP TABLE IF EXISTS think_users;
CREATE TABLE think_users (
userid mediumint(8) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户id',
companyid mediumint(8) unsigned NOT NULL COMMENT '公司id',
pid mediumint(8) NOT NULL COMMENT '父id',
username char(20) NOT NULL DEFAULT '' COMMENT '用户名',
password char(32) NOT NULL DEFAULT '' COMMENT '密码',
nickname char(20) NOT NULL DEFAULT '' COMMENT '昵称',
regdate int(10) unsigned NOT NULL COMMENT '注册时间',
lastdate int(10) unsigned NOT NULL COMMENT '最后一次登录时间',
regip char(15) NOT NULL DEFAULT '' COMMENT '注册ip',
lastip char(15) NOT NULL DEFAULT '' COMMENT '最后一次登录ip',
loginnum smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT '登录次数',
email char(32) NOT NULL DEFAULT '' COMMENT '邮箱',
mobile char(11) NOT NULL DEFAULT '' COMMENT '手机号码',
islock tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否锁定',
vip tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否会员',
overduedate int(10) unsigned NOT NULL COMMENT '账户过期时间',
status tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '状态-用于软删除',
PRIMARY KEY (userid),
UNIQUE KEY username (username) USING BTREE,
KEY email (email) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

创建模型(用于自动验证, 自动完成) :

代码语言:javascript
复制
namespace Home\Model;
use Think\Model;

class UsersModel extends Model {
/**
* 自动验证
* self::EXISTS_VALIDATE 或者0 存在字段就验证(默认)
* self::MUST_VALIDATE 或者1 必须验证
* self::VALUE_VALIDATE或者2 值不为空的时候验证
/
protected $_validate = array(
array('nickname', 'require', '昵称不能为空!'), //默认情况下用正则进行验证
array('username', 'require', '用户名不能为空!'), //默认情况下用正则进行验证
array('username', '', '该用户名已被注册!', 0, 'unique', 1), // 在新增的时候验证name字段是否唯一
array('email', '', '该邮箱已被占用', 0, 'unique', 1), // 新增的时候email字段是否唯一
array('mobile', '', '该手机号码已被占用', 0, 'unique', 1), // 新增的时候mobile字段是否唯一
// 正则验证密码 [需包含字母数字以及@
#中的一种,长度为6-22位]
array('password', '/^([a-zA-Z0-9@*#]{6,22})$/', '密码格式不正确,请重新输入!', 0),
array('repassword', 'password', '确认密码不正确', 0, 'confirm'), // 验证确认密码是否和密码一致
array('email', 'email', '邮箱格式不正确'), // 内置正则验证邮箱格式
array('mobile', '/^1[34578]\d{9}$/', '手机号码格式不正确', 0), // 正则表达式验证手机号码
array('verify', 'verify_check', '验证码错误', 0, 'function'), // 判断验证码是否正确
//array('agree', 'is_agree', '请先同意网站安全协议!', 1, 'callback'), // 判断是否勾选网站安全协议
array('agree', 'require', '请先同意网站安全协议!', 1), // 判断是否勾选网站安全协议
);

/**
 * 自动完成
 */
protected $_auto = array (
    array('password', 'md5', 3, 'function') , // 对password字段在新增和编辑的时候使md5函数处理
    array('regdate', 'time', 1, 'function'), // 对regdate字段在新增的时候写入当前时间戳
    array('regip', 'get_client_ip', 1, 'function'), // 对regip字段在新增的时候写入当前注册ip地址
);

/**
 * 判断是否同意网站安全管理协议
 * @return bool
 */
protected function is_agree()
{
    // 获取POST数据
    $agree = I('post.agree', 0, 'intval');

    // 验证
    if ($agree) {
        return true;
    } else {
        return false;
    }
}</code></pre></div></div><p>创建模型(用于自动验证, 自动完成) :</p><div class="rno-markdown-code"><div class="rno-markdown-code-toolbar"><div class="rno-markdown-code-toolbar-info"><div class="rno-markdown-code-toolbar-item is-type"><span class="is-m-hidden">代码语言:</span>javascript</div></div><div class="rno-markdown-code-toolbar-opt"><div class="rno-markdown-code-toolbar-copy"><i class="icon-copy"></i><span class="is-m-hidden">复制</span></div></div></div><div class="developer-code-block"><pre class="prism-token token line-numbers language-javascript"><code class="language-javascript" style="margin-left:0">namespace Home\Model;

use Think\Model;

class UsersModel extends Model {
/**
* 自动验证
* self::EXISTS_VALIDATE 或者0 存在字段就验证(默认)
* self::MUST_VALIDATE 或者1 必须验证
* self::VALUE_VALIDATE或者2 值不为空的时候验证
/
protected $_validate = array(
array('nickname', 'require', '昵称不能为空!'), //默认情况下用正则进行验证
array('username', 'require', '用户名不能为空!'), //默认情况下用正则进行验证
array('username', '', '该用户名已被注册!', 0, 'unique', 1), // 在新增的时候验证name字段是否唯一
array('email', '', '该邮箱已被占用', 0, 'unique', 1), // 新增的时候email字段是否唯一
array('mobile', '', '该手机号码已被占用', 0, 'unique', 1), // 新增的时候mobile字段是否唯一
// 正则验证密码 [需包含字母数字以及@
#中的一种,长度为6-22位]
array('password', '/^([a-zA-Z0-9@*#]{6,22})$/', '密码格式不正确,请重新输入!', 0),
array('repassword', 'password', '确认密码不正确', 0, 'confirm'), // 验证确认密码是否和密码一致
array('email', 'email', '邮箱格式不正确'), // 内置正则验证邮箱格式
array('mobile', '/^1[34578]\d{9}$/', '手机号码格式不正确', 0), // 正则表达式验证手机号码
array('verify', 'verify_check', '验证码错误', 0, 'function'), // 判断验证码是否正确
//array('agree', 'is_agree', '请先同意网站安全协议!', 1, 'callback'), // 判断是否勾选网站安全协议
array('agree', 'require', '请先同意网站安全协议!', 1), // 判断是否勾选网站安全协议
);

/**
 * 自动完成
 */
protected $_auto = array (
    array(&#39;password&#39;, &#39;md5&#39;, 3, &#39;function&#39;) , // 对password字段在新增和编辑的时候使md5函数处理
    array(&#39;regdate&#39;, &#39;time&#39;, 1, &#39;function&#39;), // 对regdate字段在新增的时候写入当前时间戳
    array(&#39;regip&#39;, &#39;get_client_ip&#39;, 1, &#39;function&#39;), // 对regip字段在新增的时候写入当前注册ip地址
);

/**
 * 判断是否同意网站安全管理协议
 * @return bool
 */
protected function is_agree()
{
    // 获取POST数据
    $agree = I(&#39;post.agree&#39;, 0, &#39;intval&#39;);

    // 验证
    if ($agree) {
        return true;
    } else {
        return false;
    }
}</code></pre></div></div><p>登录注册 :</p><div class="rno-markdown-code"><div class="rno-markdown-code-toolbar"><div class="rno-markdown-code-toolbar-info"><div class="rno-markdown-code-toolbar-item is-type"><span class="is-m-hidden">代码语言:</span>javascript</div></div><div class="rno-markdown-code-toolbar-opt"><div class="rno-markdown-code-toolbar-copy"><i class="icon-copy"></i><span class="is-m-hidden">复制</span></div></div></div><div class="developer-code-block"><pre class="prism-token token line-numbers language-javascript"><code class="language-javascript" style="margin-left:0">namespace Home\Controller;

use Think\Controller;

/**

  • Class LoginController

  • @package Home\Controller
    /
    class LoginController extends Controller {
    /
    *

    • 用户登录
      */
      public function login()
      {
      // 判断提交方式
      if (IS_POST) {
      // 实例化Login对象
      $login = D('login');

       // 自动验证 创建数据集
       if (!$data = $login-&gt;create()) {
           // 防止输出中文乱码
           header(&#34;Content-type: text/html; charset=utf-8&#34;);
           exit($login-&gt;getError());
       }
      
       // 组合查询条件
       $where = array();
       $where[&#39;username&#39;] = $data[&#39;username&#39;];
       $result = $login-&gt;where($where)-&gt;field(&#39;userid,username,nickname,password,lastdate,lastip&#39;)-&gt;find();
      
       // 验证用户名 对比 密码
       if ($result &amp;&amp; $result[&#39;password&#39;] == $result[&#39;password&#39;]) {
           // 存储session
           session(&#39;uid&#39;, $result[&#39;userid&#39;]);          // 当前用户id
           session(&#39;nickname&#39;, $result[&#39;nickname&#39;]);   // 当前用户昵称
           session(&#39;username&#39;, $result[&#39;username&#39;]);   // 当前用户名
           session(&#39;lastdate&#39;, $result[&#39;lastdate&#39;]);   // 上一次登录时间
           session(&#39;lastip&#39;, $result[&#39;lastip&#39;]);       // 上一次登录ip
      
           // 更新用户登录信息
           $where[&#39;userid&#39;] = session(&#39;uid&#39;);
           M(&#39;users&#39;)-&gt;where($where)-&gt;setInc(&#39;loginnum&#39;);   // 登录次数加 1
           M(&#39;users&#39;)-&gt;where($where)-&gt;save($data);   // 更新登录时间和登录ip
      
           $this-&gt;success(&#39;登录成功,正跳转至系统首页...&#39;, U(&#39;Index/index&#39;));
       } else {
           $this-&gt;error(&#39;登录失败,用户名或密码不正确!&#39;);
       }
      

      } else {
      $this->display();
      }
      }

    /**

    • 用户注册
      */
      public function register()
      {
      // 判断提交方式 做不同处理
      if (IS_POST) {
      // 实例化User对象
      $user = D('users');

       // 自动验证 创建数据集
       if (!$data = $user-&gt;create()) {
           // 防止输出中文乱码
           header(&#34;Content-type: text/html; charset=utf-8&#34;);
           exit($user-&gt;getError());
       }
      
       //插入数据库
       if ($id = $user-&gt;add($data)) {
           /* 直接注册用户为超级管理员,子用户采用邀请注册的模式,
              遂设置公司id等于注册用户id,便于管理公司用户*/
           $user-&gt;where(&#34;userid = $id&#34;)-&gt;setField(&#39;companyid&#39;, $id);
           $this-&gt;success(&#39;注册成功&#39;, U(&#39;Index/index&#39;), 2);
       } else {
           $this-&gt;error(&#39;注册失败&#39;);
       }
      

      } else {
      $this->display();
      }
      }

    /**

    • 用户注销
      */
      public function logout()
      {
      // 清楚所有session
      session(null);
      redirect(U('Login/login'), 2, '正在退出登录...');
      }

    /**

    • 验证码
      */
      public function verify()
      {
      // 实例化Verify对象
      $verify = new \Think\Verify();

      // 配置验证码参数
      $verify->fontSize = 14; // 验证码字体大小
      $verify->length = 4; // 验证码位数
      $verify->imageH = 34; // 验证码高度
      $verify->useImgBg = true; // 开启验证码背景
      $verify->useNoise = false; // 关闭验证码干扰杂点
      $verify->entry();
      }
      }

登录模版 :

代码语言:javascript
复制
<form action="SELF" method="post">
<div class="form-group has-feedback">
<input type="text" name="username" class="form-control" placeholder="用户名" />
<span class="glyphicon glyphicon-user form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input type="password" name="password" class="form-control" placeholder="密码" />
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input type="text" name="verify" class="form-control" placeholder="验证码" style="width:200px;" />
<span class="glyphicon glyphicon-qrcode form-control-feedback" style="right:120px;"></span>
<img class="verify" src="{:U(verify)}" alt="验证码" onClick="this.src=this.src+'?'+Math.random()" />
</div>
<div class="row">
<div class="col-xs-8">
<div class="checkbox icheck">
<label>
<input type="checkbox" name="remember" value="1"> 记住我
</label>
</div>
</div><!-- /.col -->
<div class="col-xs-4">
<button type="submit" class="btn btn-primary btn-block btn-flat">登录</button>
</div><!-- /.col -->
</div>
</form>

注册模版 :

代码语言:javascript
复制
<div class="register-box-body">
<p class="login-box-msg">注册一个新用户</p>
<form action="__SELF__" method="post">
<div class="form-group has-feedback">
<input type="text" name="nickname" class="form-control" placeholder="昵称" />
<span class="glyphicon glyphicon-leaf form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input type="text" name="username" class="form-control" placeholder="用户名" />
<span class="glyphicon glyphicon-user form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input type="password" name="password" class="form-control" placeholder="密码" />
<span class="glyphicon glyphicon-credit-card form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input type="password" name="repassword" class="form-control" placeholder="确认密码" />
<span class="glyphicon glyphicon-check form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input type="email" name="email" class="form-control" placeholder="邮箱" />
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input type="text" name="mobile" class="form-control" placeholder="手机号码" />
<span class="glyphicon glyphicon-phone form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input type="text" name="verify" class="form-control" placeholder="验证码" style="width:200px;" />
<span class="glyphicon glyphicon-qrcode form-control-feedback" style="right:120px;"></span>
<img class="verify" src="{:U(verify)}" alt="验证码" onClick="this.src=this.src+'?'+Math.random()" />
</div>
<div class="row">
<div class="col-xs-8">
<div class="checkbox icheck">
<label>
<input type="checkbox" name="agree" value="1"> 我同意 <a href="#">网站安全协议</a>
</label>
</div>
</div><!-- /.col -->
<div class="col-xs-4">
<button type="submit" class="btn btn-primary btn-block btn-flat">点击注册</button>
</div><!-- /.col -->
</div>
</form>
<a href="login.html" class="text-center">我已经注册了账户</a>
</div>