1.4 用户注册

1.4.1 用户注册功能概述

在用户注册时,需要填写的必填信息包括用户名、密码和E-mail。只有这些必填信息添加完整并正确时,“注册”按钮才被激活。这时用户可以选择注册或填写详细信息后再进行注册。在整个注册的过程中,用户的每一次操作,系统都将给出友好的提示来帮助用户完成注册。注册功能的运行结果如图1.9所示。

图1.9 注册页面的运行结果

用户注册功能实现包含5个核心文件:register.php(注册表单页)、register_chk.php (注册处理页)、chkname.php(检测用户名)、register.js(注册信息验证脚本)和activation.php (激活处理页)。

1.4.2 注册页面设计

注册表单页(register.php)中,主要包含填写信息的文本框、信息提示的div标签和3个相关按钮。注册页面中使用的元素如表1.1所示。

表1.1 注册页面主要元素

当用户向注册页面中的表单元素输入信息时,将会触发信息处理脚本register.js。下面逐行讲解register.js脚本页。

在register.js中,首先写了一个通用函数,来避免重复输入document.getElement ById(' …' )。这个函数的意思是返回被触发的“id=idValue”的元素对象。

      function $(idValue){
            return document.getElementById(idValue);
      }

接下来是window.onlaod事件,表示当窗体被载入时触发。function(){…}表示当页面被载入时所要进行的操作。

      window.onload = function(){
          …
      }

下面所有的代码都是上面的函数。首先将焦点定位到用户名文本框,方便用户操作。接下来声明了5个变量,这5个变量代表了5项要检测的数据的结果。当检测数据为“合格”时,代表它的变量将等于“yes”,代码如下:

            $(' regname' ).focus();                         //焦点定位到用户名文本框
            //声明5个变量,表示要检测的5项数据
            var cname1, cname2, cpwd1, cpwd2, cemail;

chkreg()函数是每一次触发键盘事件后都要调用的。该函数判断5个变量的值,只有当所有变量都等于“yes”时,“注册”按钮才会被激活。

            function chkreg(){
                if((cname1 == ' yes' ) && (cname2 == ' yes' ) && (cpwd1 == ' yes' ) && (cpwd2
                == ' yes' ) && (cemail == ' yes' )){
                  $(' regbtn' ).disabled = false;
                }else{
                  $(' regbtn' ).disabled = true;
                }
            }

接下来是验证用户名。当用户输入注册名称时,该函数会把用户的每次输入都做一下正则判断,并根据结果设置不同cname1的值,代码如下:

            //验证用户名
            $(' regname' ).onkeyup = function (){
                //获取注册名称
                name = $(' regname' ).value;
                cname2 = ' ' ;
                if(name.match(/^[a-zA-Z_]*/) == ' ' ){
                  $(' namediv' ).innerHTML = ' <font color=red>必须以字母或下画线开头</font>' ;
                  cname1 = ' ' ;
                }else if(name.length <= 3){
                  $(' namediv' ).innerHTML = ' <font color=red>注册名称必须大于3位</font>' ;
                  cname1 = ' ' ;
                }else{
                  $(' namediv' ).innerHTML = ' <font color=green>注册名称符合标准</font>' ;
                  cname1 = ' yes' ;
                }
                chkreg();
            }

当用户名文本框失去焦点时,即用户输入完毕转到页面中其他元素的时候,将检测用户名是否重复。用户名称判断使用了Ajax技术调用了chkname.php页并根据chkname.php的返回值,在div标签中显示判断结果。chkname.php页的代码将稍后给出。

            //当用户名称文本框失去焦点时,系统调用处理页查看是否存在该用户
            $(' regname' ).onblur = function(){
                name = $(' regname' ).value;                         //获取注册用户名
                //当用户名称的格式输入合格后,才进行这一步操作
                if(cname1 == ' yes' ){
                  xmlhttp.open(' get' , ' chkname.php? name=' +name, true); //创建新请求
                  xmlhttp.onreadystatechange = function(){
                        if(xmlhttp.readyState == 4){
                            if(xmlhttp.status == 200){
                                var msg = xmlhttp.responseText;    //获取响应页内容
                                if(msg == '1' ){
                                  $(' namediv' ).innerHTML="<font color=green>恭喜您,
                                  该用户名可以使用!</font>";
                                  cname2 = ' yes' ;
                                }else if(msg == '2' ){
                                  $(' namediv' ).innerHTML="<font color=red>用户名被占
                                  用!</font>";
                                  cname2 = ' ' ;
                                }else{
                              $(' namediv' ).innerHTML="<font color=red>"+msg+"</font>";
                                  cname2 = ' ' ;
                                }
                            }
                        }
                        chkreg();                          //检查是否要激活“注册”按钮
                  }
                  xmlhttp.send(null);
                }
            }

接下来是验证密码。验证密码时,除了可以限制密码的长度外,还可以判断密码的强度。例如这段代码中,6~12之间的密码都是弱,如果大于12,但密码单一,都是数字或文字,那么密码强度就为中,否则强度就为高,代码如下:

            //验证密码
            $(' regpwd1' ).onkeyup = function(){
              pwd = $(' regpwd1' ).value;
              pwd2 = $(' regpwd2' ).value;
              if(pwd.length < 6){
                  $(' pwddiv1' ).innerHTML = ' <font color=red>密码长度最少需要6位</font>' ;
                  cpwd1 = ' ' ;
              }else if(pwd.length >= 6 && pwd.length < 12){
                  $(' pwddiv1' ).innerHTML = ' <font color=green>密码符合要求。密码强度:
                  弱</font>' ;
                  cpwd1 = ' yes' ;
              }else if((pwd.match(/^[0-9]*$/)! =null) —— (pwd.match(/^[a-zA-Z]*$/) ! =
                null )){
                  $(' pwddiv1' ).innerHTML = ' <font color=green>密码符合要求。密码强度:
                  中</font>' ;
                  cpwd1 = ' yes' ;
              }else{
                  $(' pwddiv1' ).innerHTML = ' <font color=green>密码符合要求。密码强度:
                  高</font>' ;
                  cpwd1 = ' yes' ;
              }
              if(pwd2 ! = ' ' && pwd ! = pwd2){
                  $(' pwddiv2' ).innerHTML = ' <font color=red>两次密码不一致!</font>' ;
                  cpwd2 = ' ' ;
              }else if(pwd2 ! = ' ' && pwd == pwd2){
                  $(' pwddiv2' ).innerHTML = ' <font color=green>密码输入正确</font>' ;
                  cpwd2 = ' yes' ;
              }
              chkreg();
            }

二次密码的验证比较简单,只要第一、第二次密码相等就可以。

                //验证二次密码
                $(' regpwd2' ).onkeyup = function(){
                pwd1 = $(' regpwd1' ).value;
                pwd2 = $(' regpwd2' ).value;
                if(pwd1 ! = pwd2){
                    $(' pwddiv2' ).innerHTML = ' <font color=red>两次密码不一致!</font>' ;
                    cpwd2 = ' ' ;
                }else{
                    $(' pwddiv2' ).innerHTML = ' <font color=green>密码输入正确</font>' ;
                    cpwd2 = ' yes' ;
                    chkreg();
                }
            }

接下来的E-mail验证主要是对E-mail的格式进行检查,输入的字串中必须包含“@”和“.”,同时,这两个符号的位置既不能在首和尾,也不能连在一起,代码如下:

            //验证E-mail
            $(' email' ).onkeyup = function(){
              emailreg = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
              $(' email' ).value.match(emailreg);
              if($(' email' ).value.match(emailreg) == null){
                  $(' emaildiv' ).innerHTML = ' <font color=red>错误的email格式</font>' ;
                  cemail = ' ' ;
              }else{
                  $(' emaildiv' ).innerHTML = ' <font color=green>输入正确</font>' ;
                  cemail = ' yes' ;
              }
@@
              chkreg();
            }

上面的部分是对必填项的检查。如果用户希望填写更详细的资料,可以单击“详细资料”按钮,代码如下:

            //显示/隐藏详细信息
            $(' morebtn' ).onclick = function(){
@@
              if($(' morediv' ).style.display == ' ' ){
                  $(' morediv' ).style.display = ' none' ;
              }else{
                  $(' morediv' ).style.display = ' ' ;
              }
            }

所有信息添加完毕并通过验证后,就可以注册了。用户单击“注册”按钮时,该段代码应用Ajax技术将获取的用户信息以URL的形式传给register_chk.php页,并根据返回结果做出相应的处理,代码如下:

            //正式注册
            $(' regbtn' ).onclick = function(){
              $(' imgdiv' ).style.visibility = ' visible' ;
              url = ' register_chk.php? name=' +$(' regname' ).value+' &pwd=' +$(' regpwd1' ).
              value+' &email=' +$(' email' ).value;
              url += ' &question=' +$(' question' ).value+' &answer=' +$(' answer' ).value;
              url += ' &realname=' +$(' realname' ).value+' &birthday=' +$(' birthday' ).
              value;
              url += ' &telephone=' +$(' telephone' ).value+' &qq=' +$(' qq' ).value;
              alert(url);
              return false;
              xmlhttp.open(' get' , url, true);
              xmlhttp.onreadystatechange = function(){
                  if(xmlhttp.readyState == 4){
                      if(xmlhttp.status == 200){
                          msg = xmlhttp.responseText;
                          if(msg == '1' ){
                              alert(’注册成功,请到您的邮箱中获取激活码!' );
                              location=' main.php' ;
                          }else if(msg == ' -1' ){
                              alert(’您的服务器不支持POP3,请仔细检查!! ' );
                          }else{
                              alert(msg);
                          }
                      }
                      $(' imgdiv' ).style.visibility = ' hidden' ;
                  }
              }
              xmlhttp.send(null);
            }

1.4.3 检测用户名是否被占用

检测用户名是否被占用使用的是chkname.php文件,其作用是检查用户名是否重复,并且返回判断结果,该页的代码如下:

      <? php
      //载入数据库类
      include_once "conn/conn.php";
      //根据name查询tb_member表
      $sql = "select * from tb_member where name=' ".$_GET[' name' ]."' ";
      //获取查询结果的记录数
      $num = $conne->getRowsNum($sql);
      if($num == 1){                                  //如果有记录
            echo '2' ;
      }else if($num == 0){                            //如果没有记录
            echo '1' ;
      }else{
            echo $conne->msg_error();                 //否则出错
      }
      ?>

1.4.4 注册信息处理

在注册信息处理页(register_chk.php)中,将JavaScript传递过来的值连成insert语句并执行。如果添加成功,则使用邮件函数发送一封激活邮件,并弹出提示框,结果如图1.10所示。

图1.10 注册成功提示框

在处理代码中包含两种邮件的发送方法,一种是使用局域网,向指定smtp服务器中的邮箱中发送邮件。其中的cym3100@163.com邮箱是在smtp服务器中注册的测试邮箱;另一种是适用于互联网,通过指定的邮箱(mrsoft8888@sohu.com是在搜狐中注册的邮箱,用户名mrsoft8888,密码mrsoft8888)向用户提供的有效邮箱中发送邮件,处理页代码如下:

      <? php
       include_once ' conn/conn.php' ;
       require_once ' Zend/Mail.php' ;                     //调用发送邮件的文件
       require_once ' Zend/Mail/Transport/Smtp.php' ;      //调用SMTP验证文件
       $reback = '0' ;
       $url = ' http://' .$_SERVER[' SERVER_NAME' ].dirname($_SERVER[' SCRIPT_NAME' ]).' /
       activation.php' ;
       $url .= ' ? name=' .trim($_GET[' name' ]).' &pwd=' .md5(trim($_GET[' pwd' ]));
       //发送激活邮件
       $subject="激活码的获取";
        $mailbody=’注册成功。您的激活码是:' .' <a href="' .$url.' " Target
            ="_blank">' .$url.' </a><br>' .’请点击该地址,激活您的用户!' ;
        //定义邮件内容
        $envelope="mrsoft8888@sohu.com";                      //定义登录使用的邮箱
        /*smtp测试版发送邮件方式,使用smtp作为服务器
        $tr = new Zend_Mail_Transport_Smtp('192.168.1.247' );
        $mail = new Zend_Mail();
        $mail->addTo(' cym3100@163.com' , ’获取用户注册激活码’);
        $mail->setFrom(' cym3100@163.com' , ’明日科技典型模块程序测试邮箱,恭喜您用户注册成功!' );
        $mail->setSubject(’获取注册用户的激活码’);
        $mail->setBodyHtml($mailbody);
        $mail->send($tr);
        */
        /*网络版发送邮件方法*/
        $config = array(' auth' => ' login' ,
                  'username' => ' mrsoft8888' ,
                  'password' => ' mrsoft8888' );               //定义SMTP的验证参数
        //实例化验证的对象
        $transport = new Zend_Mail_Transport_Smtp(' smtp.sohu.com' , $config);
        $mail = new Zend_Mail(' GBK' );                        //实例化发送邮件对象
            $mail->setBodyHtml($mailbody);                     //发送邮件主体
            //定义邮件发送使用的邮箱
        $mail->setFrom($envelope, ’明日科技典型模块程序测试邮箱,恭喜您用户注册成功!' );
        $mail->addTo($_GET[email], ’获取用户注册激活码’);          //定义邮件的接收邮箱
        $mail->setSubject(’获取注册用户的激活码’);                 //定义邮件主题
        $mail->send($transport);                               //执行发送操作
        /*网络版发送邮件方法*/
        $sql = "insert into tb_member(name, password, question, answer, email,
            realname, birthday, telephone, qq) values(' ".trim($_GET[' name' ])."' ,
            '".md5(trim($_GET[' pwd' ]))."' , ' ".$_GET[' question' ]."' , ' ".$_GET[' answer' ]."' ,
            '".$_GET[' email' ]."' , ' ".$_GET[' realname' ]."' , ' ".$_GET[' birthday' ]."' ,
            '".$_GET[' telephone' ]."' , ' ".$_GET[' qq' ]."' )";
        $num = $conne->uidRst($sql);
        if($num == 1){
            $reback = '1' ;
        }
        echo $reback;
       ?>

1.4.5 注册用户激活

在用户注册成功后,需要登录用户填写的邮箱,浏览注册时发送的邮件,并且单击超链接,链接到activation.php文件,根据超链接传递的用户名和密码完成对指定用户表中active字段值的更新操作,即完成注册用户的激活操作。

登录mrsoft8888@sohu.com邮箱,将查看到如图1.11所示的邮件内容。

图1.11 激活邮件的运行结果

当用户进入激活页(activation.php)后,激活页将根据name字段和pwd字段来查找匹配的注册用户,如果找到将进行更新操作。激活成功后,将用户名保存到Session中,并跳转到相应的页面,代码如下:

      <? php
      session_start();
      header(' Content-Type:text/html; charset=gb2312' );
      include_once("conn/conn.php");
      if (! empty($_GET[' name' ]) && ! is_null($_GET[' name' ])){         //激活注册用户
            $num=$conne->getRowsNum("select * from tb_member where name=
            '".$_GET[' name' ]."' and password = ' ".$_ GET[' pwd' ]."' ");
            if ($num>0){
              $upnum=$conne->uidRst("update tb_member set active = 1 where name
              =' ".$_GET[' name' ]."' and password = ' ".$_GET[' pwd' ]."' ");
              if($upnum > 0){
                  $_SESSION[' name' ] = $_GET[' name' ];
                  echo "<script>alert(’用户激活成功!' ); window.location.href=
                  'main.php' ; </script>";
              }else{
                  echo "<script>alert(’您已经激活!' ); window.location.href=
                  'main.php' ; </script>";
              }
            }else{
              echo "<script>alert(’用户激活失败!' ); window.location.href=
              'register.php' ; </script>";
            }
      }
      ?>

1.4.6 免激活用户注册

上面介绍的用户注册功能中,需要将激活信息以邮件的形式发送到用户指定的邮箱中进行激活后,用户才可以使用。这里向读者介绍一种不需要激活的用户注册方式,同样以上面注册提交的数据为基础,只是修改用户注册提交数据的处理方式。就可以实现免激活的用户注册功能。该操作在register_check.php文件中完成,其关键代码如下:

      <? php
       include_once ' conn/conn.php' ;             //包含数据库连接操作文件
       $reback = '0' ;                             //定义初始变量
       $sql = "insert into tb_member(name, password, question, answer, email, realname,
            birthday, telephone, qq, active) values(' ".trim($_GET[' name' ])."' , ' ".md5(trim
            ($_GET[' pwd' ]))."' , ' ".$_GET[' question' ]."' , ' ".$_GET[' answer' ]."' , ' ".$_GET
            [' email' ]."' , ' ".$_GET[' realname' ]."' , ' ".$_GET[' birthday' ]."' , ' ".$_GET
            [' telephone' ]."' , ' ".$_GET[' qq' ]."' , '1' )";
            $num = $conne->uidRst($sql);          //执行添加语句
            if($num == 1){
                $reback = '1' ;
            }
       echo $reback;                               //输出变量值
      ?>

实践真知 说明

在本模块中要使用免激活模式来注册用户,首先应该在js\register.js文件中修改注册数据处理URL路径,将注册数据处理文件(register_chk.php)修改为register_check.php,代码如下:

      $(' regbtn' ).onclick = function(){
            $(' imgdiv' ).style.visibility = ' visible' ;
            url = ' register_chk.php? name=' +$(' regname' ).value+' &pwd=
            '+$(' regpwd1' ).value+' &email=' +$(' email' ).value;
            url += ' &question=' +$(' question' ).value+' &answer=' +$(' answer' ).value;
            url += ' &realname=' +$(' realname' ).value+' &birthday=' +$(' birthday' ).
            value;
            url += ' &telephone=' +$(' telephone' ).value+' &qq=' +$(' qq' ).value;
            xmlhttp.open(' get' , url, true);
            xmlhttp.onreadystatechange = function(){
                if(xmlhttp.readyState == 4){
                    if(xmlhttp.status == 200){
                        msg = xmlhttp.responseText;
                        if(msg == '1' ){
                            alert(’注册成功,请到您的邮箱中获取激活码!' );
                            location=' index.php' ;
                        }else if(msg == ' -1' ){
                            alert(’您的服务器不支持Zend_mail,或者邮箱填写错误。请仔细检查!! ' );
                        }else{
                            alert(msg);
                        }
                        $(' imgdiv' ).style.visibility = ' hidden' ;
                    }
                }
            }
            xmlhttp.send(null);
       }

实践真知 说明

如此,在执行用户注册数据的处理时,就会调用我们上面重新编写的register_ check.php文件,用户注册成功后可以直接登录,而不必在进行激活操作。