前端页面制作
一、介绍
1.1 基础内容
本次实验主要以前端制作为主要内容,使用纯前端知识制作用户注册登录的界面,为后续实验做铺垫。通过本实验的学习,我们可以轻松地制作类似的界面效果。由于这是 PHP 的项目课,所以我们并不需要一行一行的写 html 代码,本次课程的界面制作主要使用前端框架 bootstrap3 的模板和组件来快速搭建大方漂亮的界面,大家也会领略到 bootstrap 框架的方便之处。
如果你对页面制作不感兴趣或者对这方面比较熟悉,可以跳过本次实验,直接下载使用实验文档最后提供的代码文件。
1.2 知识点
- Bootstrap3页面布局
- Jquery脚本编写
- Ajax异步通信
1.3 实验环境
- 编程环境:Ubuntu1404
- MySQL数据库
- PHP内置服务器
- sublime,一个方便快速的文本编辑器。点击桌面左下角: 应用程序菜单/开发/sublime。
1.4 最终效果图
1.5 代码获取
你可以通过下面命令将代码下载到环境中,作为参照对比进行学习
wget http://labfile.oss.aliyuncs.com/courses/587/index.php
wget http://labfile.oss.aliyuncs.com/courses/587/check.js
二、实验步骤
2.1 页面制作
2.1.1 主页
首先在 /home/Code
目录下建立一个 web
文件夹作为我们的网站根目录,在该目录下建立 index.php
作为网站首页。使用 sublime
打开web
文件夹,对 index.php
编辑:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Index</title>
<link rel="stylesheet" href="">
</head>
<body>
<h1>hello shiyanlou</h1>
</body>
</html>
接下来启动服务器,自 PHP5.4
之后 PHP 内置了一个 Web 服务器,因此我们可以很方便地运行服务器,在 web
目录下执行以下命令:
$ php -S localhost:80 #若启动失败,可将端口号换为 8080
不出意外地话,我们的服务器就启动了,打开浏览器,输入 URL :localhost:80
好了,接下来我们将对这个页面进行精心的制作!
2.1.2 模板挑选
由于我们的课程是 PHP 的项目课,所以我们的重点不是去设计精美的界面,但是也不能太随意应付,毕竟写出来也要给别人欣赏。所以我们可以到网上去寻找好看免费的模板,自己再进行加工,就是自己的作品了。本课程主要使用 bootstrap 框架制作界面,所以首先应该去 bootstrap 官网去看看相关的优秀作品。大家平时开发也可以到上面去寻找一丝创作灵感。
经过一番寻找,我选择了这个模板:
大家也可以选择自己喜欢的模板,制作出自己喜欢的界面。我将会对这个模板页面进行一下改造,首先,先教大家如何使用这个模板。
-
复制源代码:查看该模板的源代码,全部复制并粘贴到我们自己
index.php
中(覆盖之前的测试代码); -
使用 css:在 web 目录下建立一个 public 文件夹,并在其下建立 img,css,js文件夹,分别用来放置我们对应的文件。
我们可以看到模板的源代码的header中有这样一段注释:
<!-- Custom styles for this template -->
下面就是该模板所用的自定义的 css 文件。在网页中单击 css 链接,复制 css 代码,存放到public/css/start.css
文件(自行建立文件)。 -
调整引用位置:在
index.php
使用相对路径调整 css 文件的引用路径。 -
标签页图标:自行找一个 ico 文件放到
public/img
下,并修改<link rel="icon" href="public/img/xxxx.ico">
,调整引用目录
2.1.3 目录结构及修改后代码
目录结构:
Index.php
代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="public/img/favicon.ico">
<title>Index</title>
<!-- Bootstrap core CSS -->
<link href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="public/css/start.css" rel="stylesheet">
<link href="public/css/footer.css" rel="stylesheet">
</head>
<body>
<!-- 导航栏 -->
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<!-- 这里做了修改 -->
<li class="active"><a href="#">Home</a></li>
<li><a href="#register">Register</a></li>
<li><a href="#login">Login</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<!-- 页面主体内容 -->
<div class="container">
<div class="content">
<div class="starter-template">
<!-- 这里做了修改,其他地方自由发挥 -->
<h1>Welcome To ShiYanLou</h1>
<p class="lead">Use this document as a way to quickly start any new project.<br> All you get is this text and a mostly barebones HTML document.</p>
</div>
</div>
</div><!-- /.container -->
<!-- 网页底部 -->
<footer class="footer">
<div class="container">
<p class="text-muted">
<h2><a href="http://www.shiyanlou.com" title="www.shiyanlou.com" style="color: blue;">www.shiyanlou.com</a></h2>
</p>
</div>
</footer>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>
这里我还添加了一个网页的 footer
,对应的 footer.css
文件代码:
/* Sticky footer styles
-------------------------------------------------- */
.footer {
position: absolute;
bottom: 0;
width: 100%;
/* Set the fixed height of the footer here */
height: 60px;
text-align:center;
background-color: #f5f5f5;
}
对应的 start.css
的代码:
body {
padding-top: 50px;
}
.starter-template {
padding: 40px 15px;
text-align: center;
}
现在再次打开 localhost:80 ,应该就可以看到一个漂亮的首页了,而且还是响应式的布局。这里展示我的首页!
2.1.4 注册表单制作
我们将把注册和登陆的表单全部放到 index.php 中。为了美观,我们把表单样式做成模糊框样式的效果。
这里我们要使用到 bootstrap 的模糊框的 js 插件 modals 。
把模糊框的代码片段放到 container
的 div 中去。将它作为注册的表单。同时修改导航栏的 register
按钮的相关参数和模糊框的id,使之与模糊框对应起来。
<li><a href="#Register" data-toggle="modal" data-target="#register">Register</a></li>
注册表单代码:
<!-- 页面主体内容 -->
<div class="container">
<div class="content">
<div class="starter-template">
<!-- 这里做了修改,其他地方自由发挥 -->
<h1>Welcome To ShiYanLou</h1>
<p class="lead">Use this document as a way to quickly start any new project.<br> All you get is this text and a mostly barebones HTML document.</p>
</div>
<!-- 注册表单 -->
<div class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" id="register" aria-labelledby="myLargeModalLabel">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Register</h4>
</div>
<form action="" method="post" accept-charset="utf-8" class="form-horizontal">
<div class="modal-body">
<div class="form-group">
<label for="username" class="col-sm-4 control-label">Name:</label>
<div class="col-sm-6">
<input type="text" class="form-control" name="username" id="username" minlength="2" maxlength="20" placeholder="username" required="">
</div>
<!-- 错误提示信息 -->
<h6 style="color: red;" id="dis_un"></h6>
</div>
<div class="form-group">
<label for="email" class="col-sm-4 control-label">Email:</label>
<div class="col-sm-6">
<input type="email" class="form-control" name="email" id="remail" placeholder="Email" required="">
</div>
<!-- 错误提示信息 -->
<h6 style="color: red;" id="dis_em"></h6>
</div>
<div class="form-group">
<label for="password" class="col-sm-4 control-label">Password:</label>
<div class="col-sm-6">
<input type="password" class="form-control" name="password" id="password" placeholder="password" minlength="6" maxlength="20" required="">
</div>
<!-- 错误提示信息 -->
<h6 style="color: red;" id="dis_pwd"></h6>
</div>
<div class="form-group">
<label for="confirm" class="col-sm-4 control-label">Confirm password:</label>
<div class="col-sm-6">
<input type="password" class="form-control" name="confirm" id="confirm" placeholder="confirm" minlength="6" maxlength="20" required="">
</div>
<!-- 错误提示信息 -->
<h6 style="color: red;" id="dis_con_pwd"></h6>
</div>
<div class="form-group">
<label for="code" class="col-sm-4 control-label"> verification code :</label>
<div class="col-sm-6">
<input type="text" class="form-control" name="code" id="code" placeholder="verification code" required="" maxlength="4" size="100">
</div>
</div>
<div class="form-group">
<div class="col-sm-12" style="center">
<img src="#" alt="" id="codeimg" >
<a href="#" title="Switch">Click to Switch</a>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal" style="float: left;">Close</button>
<input type="reset" class="btn btn-warning" value ="reset" />
<button type="submit" class="btn btn-primary" id="reg">register</button>
</div>
</form>
</div>
</div>
</div>
</div><!-- /.content -->
</div><!-- /.container -->
修改完以上代码,保存之后,再次打开主页,点击 register 按钮,就能看到一个好看的模糊框表单:
2.1.5 登陆表单制作
参照注册表单相似的做法,我们快速搭建一个登录表单
修改导航栏菜单:
<li><a href="#Login" data-toggle="modal" data-target="#login">Login</a></li>
在注册表单之后添加以下登陆表单代码:
<!-- 登陆表单 -->
<div class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" id="login" aria-labelledby="myLargeModalLabel">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Login</h4>
</div>
<form action="" method="post" accept-charset="utf-8" class="form-horizontal">
<div class="modal-body">
<div class="form-group">
<label for="email" class="col-sm-4 control-label">Email:</label>
<div class="col-sm-6">
<input type="email" class="form-control" name="email" id="email" placeholder="Email" required="">
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-4 control-label">Password:</label>
<div class="col-sm-6">
<input type="password" class="form-control" name="password" placeholder="password" minlength="6" maxlength="20" required="">
</div>
</div>
<div class="form-group">
<label for="code" class="col-sm-4 control-label"> verification code :</label>
<div class="col-sm-6">
<input type="text" class="form-control" name="code" id="code" placeholder="verification code" required="" maxlength="4">
</div>
</div>
<div class="form-group">
<div class="col-sm-12" style="text-align:center">
<img src="#" alt="" id="codeimg">
<span>Click to Switch</span>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal" style="float: left;">Close</button>
<input type="reset" class="btn btn-warning" value ="reset" />
<button type="submit" class="btn btn-primary" name="login">Login</button>
</div>
</form>
</div>
</div>
</div>
现在打开主页,点击登陆按钮。
2.2 Js 脚本编写
2.2.1 分析脚本功能
我们经常会填写各种各样的表单,也经常会有这样的体验:当你输入数据有误或者不符合规范时候,表单页面就会给出各种错误提示,让你去改正。比如让你输入邮箱地址,你却输入了电话号码,这就是不符合规范的。当你填写用户名的时候,如果网站要求用户名具有唯一性,那么就需要对你的用户名进行检测,并给出相关提示,比如 ‘用户名已被注册’等信息。这些功能大部分都是通过前端 js 代码实现的。这样做的原因,一方面是为了让表单输入更人性化,节约输入成本。另一方面也是为了减轻后台服务器的压力。本次实验我们也会带着大家做一些表单的输入检测,如果你细心的话,可能已经注意到了,我在注册表单的输入框之后添加了对应的错误提示代码。由于注册和登陆表单功能类似,为了示范作用,我们这里只做注册表单的 js 代码,登陆部分可以留做作业,大家自己去完善。
我们需要实现的 js 功能:
- 用户名唯一性检测
- 邮箱格式和唯一性检测
- 密码与确认密码输入检测
Javascript库:Jquery
2.2.2 代码编写
为了目录结构的规范性,我们先在 public/js/ 下建立 check.js。并在 index.php 底部添加引入代码:
<script src="public/js/check.js"></script>
接下来就开始认真的写 js 代码了!
为了体现代码的规范性,我将各个功能封装为函数,最后再统一调用。
$(document).ready(function() {
var nameFlag = true; //准备一个用户名的可用性标识
var emailFlag = true; //准备一个邮箱的可用性标识
var pwdFlag = true; //准备一个密码的可行性标识
//此处添加检测方法
function checkName (){} //检测用户名
function checkEmail (){} //邮箱检测
function checkPassword (){} //密码检测
function checkSubmit (){} //表单提交检测
checkName ();
checkEmail ();
checkPassword ();
checkSubmit ();
})
2.2.3 用户名检测
这里我采用实时的方法对用户名的输入做检测:当用户输入一个字符,就做一次检测,判断合法性和唯一性。因为要检测用户名唯一性,就需要从数据库里去查找用户名,这涉及到后台代码的功能,不过现在我们只关心前台的功能,这里使用 Ajax 与后台交互,实现实时检测。代码如下:
function checkName () { //检测用户名
$('#username').keyup(function() { //用户输入一个字符就触发响应
var length = $(this).val().length;
if ( length >= 2 && length <= 20 ) { //判断用户名长度 2至20位之间
//发送用户名,检测的类型为 name
$.post('##', {username: $(this).val(),type:'name'}, function(data, textStatus, xhr) {
if (textStatus == 'success') {
if (data == '1') { //如果后台返回1,则表示此用户名已被注册
$('#dis_un').text('UserName is already registered'); //给出错误提示
nameFlag = false;
}else{ //用户名可以使用
$('#dis_un').text(''); //去掉错误提示文字
nameFlag = true;
}
}
});
}else{ //长度不符合则不进行检测
$('#dis_un').text('');
}
});
}
2.2.4 注册邮箱检测
这里的邮箱输入,我们不仅需要对其做唯一性检测,还需要做格式检测,判断用户输入是否是邮箱格式。我们也需要使用 Ajax 与后台交互确认唯一性,不过不需要像用户名那样实时检测,只需要在其失去焦点之后就开始检测,代码如下:
function checkEmail () { //邮箱检测
$('#remail').blur(function() { //注册邮箱失去焦点才检测
if ($(this).val() != '') { //输入不为空就检测
var reg = /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/; //正则表达式判断邮箱格式
if (reg.test($(this).val())) { //是邮箱格式
$.post('##', {email: $(this).val(),type: 'email'}, function(data, textStatus, xhr) {
if (textStatus == 'success') {
if (data == '1') { //后台返回1 表示已被注册
$('#dis_em').text('E-mail is already registered');
emailFlag = false;
}else{ //邮箱可用
$('#dis_em').text('');
emailFlag = true;
}
}
});
}else{ //不是邮箱格式
$('#dis_em').text('E-mail format is incorrect');
emailFlag = false;
}
}else{ //为空,不显示提示文字
$('#dis_em').text('');
}
});
}
2.2.5 密码与确认密码检测
- 密码输入的规则:不能为空,长度至少为6位。
- 确认密码规则:不能为空,长度至少6位。当上面输入密码不为空,确认密码与输入密码须一致。
基于以上规则,实现代码:
function checkPassword () { //密码检测
$('#password').blur(function(){
if ($(this).val() == '') {
$('#dis_pwd').text('Password cannot be empty');
}else if($(this).val().length < 6){
$('#dis_pwd').text('Passwords must be at least six');
}else{
$('#dis_pwd').text('');
}
});
$('#confirm').blur(function() { //确认密码检测
var val = $('#password').val();
if (val != '') {
if ($(this).val() == '') {
$('#dis_con_pwd').text('Please confirm your password');
pwdFlag = false;
}else if($(this).val() != val){
$('#dis_con_pwd').text('Confirm password inconsistent');
pwdFlag = false;
}else{
$('#dis_con_pwd').text('');
pwdFlag = true;
}
}else{
$('#dis_con_pwd').text('');
pwdFlag = false;
}
});
}
2.2.6 提交检测
当点击表单注册按钮时,我们需要判断表单界面是否存在错误,若有误,则提示检测页面信息,否则提交。
function checkSubmit () {
$('#reg').click(function() {
if (!(nameFlag && emailFlag && pwdFlag)) { //用户名标识 && 邮箱标识 && 密码标识
alert('Please check page info!');
return false;
}
});
}
至此,注册表单部分的js代码就写完了,可能写的不是很完善,但是希望可以抛砖引玉。大家也可以自行编写相关的 js 检测代码。
2.2.7 运行效果
当注册表单输入有误时,点击了 register 按钮:
部分需要与后台交互配合的效果需要在后续的实验中才能实现:用户名与邮箱的唯一性检测。
三、实验总结
本次实验主要以制作注册登陆页面为主,让大家学会如何使用免费的模板,以及相应的表单制作。虽然这是 PHP 的项目课,但是作为一名 PHP 程序员,这些简单的前端技术和简单的页面制作也是必须要掌握的。虽然做出来的页面不是很精美,但是也达到了我们想要的效果。如果有兴趣的同学,可以自行设计精美的网页。
四、课后作业
参考注册表单的js代码,自行设计编写登陆表单的输入检测 js 脚本。
验证码制作
一、实验介绍
1.1 实验内容
本次实验将会带领大家使用面向对象的思想封装一个验证码类。并在注册和登陆界面展示使用。通过本次实验的学习,你将会领悟到 PHP 的 OOP 思想,以及 GD 库的使用,验证码生成。
1.2 涉及到的知识点
- PHP编程
- GD库使用
- OOP编程
1.2 实验环境
- 实验楼在线编程环境
- PHP内置服务器
- sublime,一个方便快速的文本编辑器。点击桌面左下角: 应用程序菜单/开发/sublime
1.3 效果图
二、封装验证码类
2.1 建立目录以及准备字体
在 web 目录下建立一个 admin
目录作为我们的后台目录,存放后台代码文件。在 admin
下建立一个 fonts
目录,用于存放制作验证码所需字体。
在 admin 下新建一个 Captcha.php
文件,这就是我们需要编辑的验证码类文件。
当前目录层次结构:
编辑 Captcha.php
文件:
<?php
/**
* Captcha class
*/
class Captcha
{
function __construct()
{
# code...
}
}
添加该类的私有属性和构造方法:
<?php
/**
* Captcha class
*/
class Captcha
{
private $codeNum; //验证码位数
private $width; //验证码图片宽度
private $height; //验证码图片高度
private $img; //图像资源句柄
private $lineFlag; //是否生成干扰线条
private $piexFlag; //是否生成干扰点
private $fontSize; //字体大小
private $code; //验证码字符
private $string; //生成验证码的字符集
private $font; //字体
function __construct($codeNum = 4,$height = 50,$width = 150,$fontSize = 20,$lineFlag = true,$piexFlag = true)
{
$this->string = 'qwertyupmkjnhbgvfcdsxa123456789'; //去除一些相近的字符
$this->codeNum = $codeNum;
$this->height = $height;
$this->width = $width;
$this->lineFlag = $lineFlag;
$this->piexFlag = $piexFlag;
$this->font = dirname(__FILE__).'/fonts/consola.ttf';
$this->fontSize = $fontSize;
}
}
字体文件可通过以下命令下载到 fonts 目录:
$ wget http://labfile.oss.aliyuncs.com/courses/587/consola.ttf
接下来开始编写具体的方法:
-
创建图像资源句柄
//创建图像资源 public function createImage(){ $this->img = imagecreate($this->width, $this->height); //创建图像资源 imagecolorallocate($this->img,mt_rand(0,100),mt_rand(0,100),mt_rand(0,100)); //填充图像背景(使用浅色) }
用到的相关函数
- imagecreate:新建一个基于调色板的图像
- imagecolorallocate:为一幅图像分配颜色
- mt_rand:生成更好的随机数
-
创建验证码字符串并输出到图像
//创建验证码 public function createCode(){ $strlen = strlen($this->string)-1; for ($i=0; $i < $this->codeNum; $i++) { $this->code .= $this->string[mt_rand(0,$strlen)]; //从字符集中随机取出四个字符拼接 } $_SESSION['code'] = $this->code; //加入 session 中 //计算每个字符间距 $diff = $this->width/$this->codeNum; for ($i=0; $i < $this->codeNum; $i++) { //为每个字符生成颜色(使用深色) $txtColor = imagecolorallocate($this->img,mt_rand(100,255),mt_rand(100,255),mt_rand(100,255)); //写入图像 imagettftext($this->img, $this->fontSize, mt_rand(-30,30), $diff*$i+mt_rand(3,8), mt_rand(20,$this->height-10), $txtColor, $this->font, $this->code[$i]); } }
用到的相关函数:
- imagettftext:用 TrueType 字体向图像写入文本
-
创建干扰线条
//创建干扰线条(默认四条) public function createLines(){ for ($i=0; $i < 4; $i++) { $color = imagecolorallocate($this->img,mt_rand(0,155),mt_rand(0,155),mt_rand(0,155)); //使用浅色 imageline($this->img,mt_rand(0,$this->width),mt_rand(0,$this->height),mt_rand(0,$this->width),mt_rand(0,$this->height),$color); } }
用到的相关函数:
- imageline:画一条线段
-
创建干扰点
//创建干扰点 (默认一百个点) public function createPiex(){ for ($i=0; $i < 100; $i++) { $color = imagecolorallocate($this->img,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255)); imagesetpixel($this->img,mt_rand(0,$this->width),mt_rand(0,$this->height),$color); } }
使用的相关函数:
- imagesetpixel:画一个单一像素
-
对外输出图像:
public function show() { $this->createImage(); $this->createCode(); if ($this->lineFlag) { //是否创建干扰线条 $this->createLines(); } if ($this->piexFlag) { //是否创建干扰点 $this->createPiex(); } header('Content-type:image/png'); //请求页面的内容是png格式的图像 imagepng($this->img); //以png格式输出图像 imagedestroy($this->img); //清除图像资源,释放内存 }
用到的相关函数:
- imagepng:以 PNG 格式将图像输出到浏览器或文件
- imagedestroy:销毁一图像
-
对外提供验证码:
public function getCode(){ return $this->code; }
完整代码如下:
<?php
/**
* Captcha class
*/
class Captcha
{
private $codeNum;
private $width;
private $height;
private $img;
private $lineFlag;
private $piexFlag;
private $fontSize;
private $code;
private $string;
private $font;
function __construct($codeNum = 4,$height = 50,$width = 150,$fontSize = 20,$lineFlag = true,$piexFlag = true)
{
$this->string = 'qwertyupmkjnhbgvfcdsxa123456789';
$this->codeNum = $codeNum;
$this->height = $height;
$this->width = $width;
$this->lineFlag = $lineFlag;
$this->piexFlag = $piexFlag;
$this->font = dirname(__FILE__).'/fonts/consola.ttf';
$this->fontSize = $fontSize;
}
public function createImage(){
$this->img = imagecreate($this->width, $this->height);
imagecolorallocate($this->img,mt_rand(0,100),mt_rand(0,100),mt_rand(0,100));
}
public function createCode(){
$strlen = strlen($this->string)-1;
for ($i=0; $i < $this->codeNum; $i++) {
$this->code .= $this->string[mt_rand(0,$strlen)];
}
$_SESSION['code'] = $this->code;
$diff = $this->width/$this->codeNum;
for ($i=0; $i < $this->codeNum; $i++) {
$txtColor = imagecolorallocate($this->img,mt_rand(100,255),mt_rand(100,255),mt_rand(100,255));
imagettftext($this->img, $this->fontSize, mt_rand(-30,30), $diff*$i+mt_rand(3,8), mt_rand(20,$this->height-10), $txtColor, $this->font, $this->code[$i]);
}
}
public function createLines(){
for ($i=0; $i < 4; $i++) {
$color = imagecolorallocate($this->img,mt_rand(0,155),mt_rand(0,155),mt_rand(0,155));
imageline($this->img,mt_rand(0,$this->width),mt_rand(0,$this->height),mt_rand(0,$this->width),mt_rand(0,$this->height),$color);
}
}
public function createPiexs(){
for ($i=0; $i < 100; $i++) {
$color = imagecolorallocate($this->img,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255));
imagesetpixel($this->img,mt_rand(0,$this->width),mt_rand(0,$this->height),$color);
}
}
public function show()
{
$this->createImage();
$this->createCode();
if ($this->lineFlag) {
$this->createLines();
}
if ($this->piexFlag) {
$this->createPiexs();
}
header('Content-type:image/png');
imagepng($this->img);
imagedestroy($this->img);
}
public function getCode(){
return $this->code;
}
}
以上就是验证码类的全部代码。看起来确实挺简单的,不过用的图像处理函数比较多,上面相关的函数我也做了必要的链接和用途说明。这些函数也不用死记硬背,遇到不清楚的,随时查阅 PHP 官方文档,最重要的是还有中文文档。
2.2 使用验证码
既然已经封装完毕,那就可以开始使用了。这里为了方便,直接在 Captcha
类的下方调用该类:
session_start(); //开启session
$captcha = new Captcha(); //实例化验证码类(可自定义参数)
$captcha->show(); //调用输出
三、前端展示
后端已经准备好了验证码,前端界面就可以展示了,修改 index.php
中的注册与登陆表单的验证码部分:
<div class="form-group">
<div class="col-sm-12" style="text-align: center">
<img src="admin/Captcha.php" alt="" id="codeimg" onclick="javascript:this.src = 'admin/Captcha.php?'+Math.random();">
<span>Click to Switch</span>
</div>
</div>
img
标签添加了点击事件的 js 代码,这样就可以实现点击更换验证码的功能!
效果图:
四、实验总结
到目前为止,我们的验证码模块基本就完成了。学习到这里,大家应该对面向对象编程有了进一步的理解。也领悟到了一丝 OOP 思想。OOP 的三大特征:封装,继承,多态。我们这里只用到了一点封装的思想。大家可以继续完善和改进这个验证码类,设计出更加完美的类。这个实验我们也体会到了PHP 的函数很多,不要死记硬背,多看官方文档。
https://www.shiyanlou.com/courses/587/labs/1968/document
实现注册登陆功能
一、实验介绍
1.1 实验内容
本次实验将接着上次实验继续进行。利用 OOP 思想封装注册和登陆的后台逻辑,与前台配合实现注册登陆功能。
1.2 实验知识点
- PHP编程
- mysqli 扩展对数据库操作
- session会话
1.3 实验环境
-
sublime,一个方便快速的文本编辑器。点击桌面左下角: 应用程序菜单/开发/sublime。
-
MySQL数据库,使用下面的命令开启服务:
$ sudo service mysql start # 自行建立 web 数据库,users 表:id,username,email,password # 可使用以下 SQL 语句建立数据表: CREATE TABLE users( id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, username VARCHAR(20) NOT NULL, email VARCHAR(50) NOT NULL, password CHAR(32) NOT NULL );
-
开启服务器:
$ php -S localhost:80 #若启动失败,可将端口号换为 8080
二、实现注册功能
2.1 建立文件
在 admin 目录下建立 Register.php
作为后台登陆处理程序,稍后我们将会在其中封装具体的注册逻辑。
同时修改首页中注册表单的提交地址。
<form action="admin/Register.php" method="post" accept-charset="utf-8" class="form-horizontal">
新建配置文件,因为要使用到数据库,需要使用一些连接参数。我们可以单独建立一个配置文件,把这些参数都定义好。
在 web 目录下建立一个 config.php 文件,这就是我们的配置文件了,先定义一些数据库的连接参数:
<?php
session_start(); //开启session,在其他位置引用时可以自动开始
define('DB_HOST', '127.0.0.1');
define('DB_NAME', 'web');
define('DB_USER', 'root');
define('DB_PWD', '');
前提是你在数据库里已经建立好了 web
数据库和 users
表。
2.2 逻辑编码
-
定义类并添加属性和构造方法:
<?php /** * register */ class Register { private $username; //用户名 private $db; //数据库实例 private $email; //邮箱 private $pwd; //密码 private $con; //确认密码 private $code; //验证码 function __construct() { if (!isset($_POST['type'])) { // 若不是通过post方式访问,则返回 echo "<script>alert('You access the page does not exist!');history.go(-1);</script>"; exit(); } require '../config.php'; //引入配置文件 $this->db = new mysqli(DB_HOST,DB_USER,DB_PWD,DB_NAME) or die('数据库连接异常'); //实例化mysqli连接 } }
-
判断用户名唯一性(结合前端 Ajax)
public function uniqueName() { //判断是否是通过ajax方式提交数据 if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) ) { if('xmlhttprequest' == strtolower($_SERVER['HTTP_X_REQUESTED_WITH'])){ $this->username = $_POST['username']; //接受post的用户名 $sql = "SELECT count(*) FROM users WHERE username = '".$this->username."'"; //构造查询语句 $count = mysqli_fetch_row($this->db->query($sql))[0];//获取结果集中索引为0的值 if ($count) { //$count不为0,则存在相同的用户名 echo "1"; }else{ echo "0"; } }else{ //不是ajax方式 echo "hello world"; } }else{ //不是ajax方式 echo "hello world"; } }
-
判断邮箱唯一性(结合前端 Ajax)
public function uniqueEmail() { if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) ) { if('xmlhttprequest' == strtolower($_SERVER['HTTP_X_REQUESTED_WITH'])){ $this->email = $_POST['email']; $sql = "SELECT count(*) FROM users WHERE email = '".$this->email."'"; $count = mysqli_fetch_row($this->db->query($sql))[0]; if ($count) { echo "1"; }else{ echo "0"; } }else{ echo "hello world"; } }else{ echo "hello world"; } }
-
检测验证码
public function checkCode() { //判断输入的验证码是否与session中的验证码一致 if ($this->code != $_SESSION['code']) { echo "<script>alert('Verification code is not correct.please try again!');history.go(-1);</script>"; exit(); } }
-
检测邮箱格式(正则)
public function checkEmail() { $pattern = "/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i"; if (!preg_match($pattern,$this->email)) { echo "<script>alert('Email format incorrect.please try again!');history.go(-1);</script>"; exit(); } }
-
用户名格式(长度)
public function checkName() { $length = strlen($this->username); if (trim($this->username) == '' || $length < 2 || $length > 20) { echo "<script>alert('UserName format incorrect.please try again!');history.go(-1);</script>"; exit(); } }
-
检测密码
public function checkPwd(){ //密码不能为空格,长度介于6至20之间 if (trim($this->pwd) == '' || strlen($this->pwd) < 6 || strlen($this->pwd) > 20) { echo "<script>alert('PassWord format incorrect.please try again!');history.go(-1);</script>"; exit(); } //确认密码必须与密码保持一致 if ($this->pwd != $this->con) { echo "<script>alert('Confirm password do not match.please try again!');history.go(-1);</script>"; exit(); } //加密密码 $this->pwd = md5($this->pwd); }
-
执行注册操作
public function doRegister() { $this->email = $_POST['email']; //接受参数 $this->username = $_POST['username']; $this->code = $_POST['code']; $this->pwd = $_POST['password']; $this->con = $_POST['confirm']; $this->checkCode(); //检测数据 $this->checkPwd(); $this->checkName(); $this->checkEmail(); $sql = "INSERT INTO users (username, email, password) VALUES ('".$this->username."','".$this->email."','".$this->pwd."')"; $result = $this->db->query($sql); //将数据录入数据库 if ($result) { $this->db->close(); //不要忘记关闭数据库连接 echo "<script>alert('Successful registration, please log in!');location.href = '/';</script>"; exit(); }else{ echo $this->db->error; exit(); } }
看到这里,你可能会有些疑惑,前端的输入数据我们已经通过
js
做了格式检测,,为什么这里还要做相同的检测?这涉及到一点网络安全的知识。设计web应用时,一定要牢住的一条准则就是:永远不要相信客户端的输入 !前端 js 检测设计得再好,在有技术基础的人面前,都形同虚设。所以,不要指望你写的那点 js 能真正对数据过滤有多大的作用,那只适用于普通用户和技术小白而已。
-
判断请求数据类型
如果你对注册页面还有印象的话,应该知道,我们提交的数据可以有三种类型。其中两种是通过 Ajax 提交,一种是通过表单页面提交,所以在设计的时候,我添加了一个
type
的参数以区别是哪种数据的提交。所以我们在执行相关操作之前需要加以判断:$reg = new Register(); //先实例化注册类 switch ($_POST['type']) { //根据传递的type执行对应操作 case 'name': //ajax方式提交的用户名唯一性检测 $reg->uniqueName(); break; case 'email': //ajax方式提交的邮箱唯一性检测 $reg->uniqueEmail(); break; case 'all': //通过表单提交的注册操作 $reg->doRegister(); break; default: echo "hello world"; break; }
2.3 前端修改
-
修改 js 脚本
将用户名和邮箱的 ajax 请求地址稍作修改:
//用户名唯一性检测 $.post('admin/Register.php', {username: $(this).val(),type:'name'}, function(data, textStatus, xhr) { ***** } //邮箱唯一性检测 $.post('admin/Rregister.php', {email: $(this).val(),type: 'email'}, function(data, textStatus, xhr) { ***** }
-
修改注册表单提交地址
<form action="admin/Register.php" method="post" accept-charset="utf-8" class="form-horizontal">
-
向注册表单添加一项
type
的输入标签,表示这是注册表单提交:<input type="hidden" name="type" value="all">
三、实现登陆功能
和注册功能类似,登陆功能也可以封装成为一个登陆类,其中主要的方法有以下几个:
- 检查验证码
- 检查邮箱格式和密码格式
- 检查用户是否存在
- 执行登陆操作
3.1 封装登陆类
-
首先在 admin 目录下建立一个 Login.php 作为登陆处理文件。定义类,添加属性和构造方法:
<?php /** * login */ class Login { private $email; //登陆邮箱 private $password; //登陆密码 private $code; //验证码 function __construct() { if (!isset($_POST['login'])) { //非 post 方式提交不被接受 echo "<script>alert('You access the page does not exist!');history.go(-1);</script>"; exit(); } require '../config.php'; //引入配置文件 $this->email = $_POST['email']; $this->password = $_POST['password']; $this->code = $_POST['code']; } }
- 检查登录邮箱格式(同上注册方法)
-
检查密码格式
//验证密码格式 public function checkPwd() { if (!trim($this->password) == '') { $strlen = strlen($this->password); if ($strlen < 6 || $strlen > 20) { echo "<script>alert('Password length of illegal.please try again!');history.go(-1);</script>"; exit(); }else{ $this->password = md5($this->password); } }else{ echo "<script>alert('Password cannot be blank.please try again!');history.go(-1);</script>"; exit(); } }
-
检查验证码(同上注册)
-
检查用户是否存在
//数据库验证 public function checkUser() { $db = new mysqli(DB_HOST,DB_USER,DB_PWD,DB_NAME) or die('数据库连接异常'); $sql = "SELECT username FROM users WHERE email = '".$this->email."' and password = '".$this->password."'"; $result = mysqli_fetch_row($db->query($sql))[0]; if (!$result) { //不存在,登陆失败 echo "<script>alert('Email or password is incorrect.please try again!');history.go(-1);</script>"; exit(); }else{ //用户存在,登陆成功 $_SESSION['user'] = $result; //将用户名保存到 session 会话中 $db->close(); //不要忘记关闭数据库连接 //输出登陆成功信息,并跳转到主页(这里暂时为登陆和注册首页) echo "<script>alert('Login Success!');location.href = '/index.php'</script>"; exit(); } }
-
执行以上操作:
public function doLogin() { $this->checkCode(); $this->checkEmail(); $this->checkPwd(); $this->checkUser(); }
-
调用登陆类
$login = new Login(); $login->doLogin();
-
修改登陆表单提交地址
<form action="admin/Login.php" method="post" accept-charset="utf-8" class="form-horizontal">
四、功能测试
现在当你在注册页面输入用户名和邮箱时,便可做出动态响应。
输入有误:
注册成功:
登陆成功:
五、实验总结
到目前为止,简单的用户注册登陆功能就基本实现了。不过尚有很多不足。比如跳转的用户主页没有设计,还可以添加一个 记住我 的功能,页面查看的权限(是否登录),提高代码复用率等等。我们将会在下一个实验继续完善我们的项目。
功能完善
一、实验介绍
1.1 实验内容
本实验将对现有的程序代码进行优化完善,并增加新的功能以及访问权限的控制。
1.2 实验知识点
- Html代码复用
- 建立用户主页
- 使用 cookie 实现
记住我
功能并且自动登录 - 浏览页面访问限制
1.3 实验环境
-
sublime,一个方便快速的文本编辑器。点击桌面左下角: 应用程序菜单/开发/sublime。
-
MySQL,使用下面的命令开启服务:
$ sudo service mysql start # 使用上一个实验建立的数据库和数据表
-
开启服务器:
$ php -S localhost:80 #若不能启动成功,可将端口号换为 8080
1.4 源码下载
你可以通过以下方式获取本项目的全部示例代码:
wget http://labfile.oss.aliyuncs.com/courses/587/web.zip
二、前端优化
2.1 HTML复用
查看 index.php
代码,我们可以把整个网页分为三大区域:头部(header)、导航栏(nav)、主体(container)、底部(footer)。其中头部,导航栏和底部基本是每个页面都需要使用到的部分,只有主体的内容会发生变化。所以我们可以想办法把 header nav 和 footer 提取出来,作为单独的部件,index 页面通过引入文件的方式再把他们引入到自身。这样一来,提取出来的 header nav 和 footer 也可以供其他需要的页面使用而不用单独在每个页面上都手写一份。这种方式类似于模板布局。
首先在 public 目录下建立一个 layouts 的目录,用于存放提取出来的部件。在其下建立 header.php ,nav.php, footer.php。
将 index.php 中的相应代码剪切进来:
-
header.php
<head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <meta name="description" content=""> <meta name="author" content=""> <link rel="icon" href="public/img/favicon.ico"> <title>web page</title> <!-- Bootstrap core CSS --> <link href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"> <!-- Custom styles for this template --> <link href= "public/css/start.css" rel="stylesheet"> <link rel="stylesheet" type="text/css" href="public/css/footer.css"> </head>
-
nav.php
<nav class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">ShiYanLou</a> </div> <div id="navbar" class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <!-- 这里做了修改 --> <li class="active"><a href="#">Home</a></li> <li><a href="#Register" data-toggle="modal" data-target="#register">Register</a></li> <li><a href="#Register" data-toggle="modal" data-target="#login">Login</a></li> </ul> </div><!--/.nav-collapse --> </div> </nav>
-
footer.php
<!-- 网页底部 --> <footer class="footer"> <div class="container"> <p class="text-muted"> <h2><a href="http://www.shiyanlou.com" title="www.shiyanlou.com" style="color: blue;">www.shiyanlou.com</a></h2> </p> </div> </footer>
在 index.php 中引入对应文件:
<!DOCTYPE html>
<html lang="zh-CN">
<!-- header部分 -->
<?php require_once 'public/layouts/header.php' ?>
<body>
<!-- 导航栏 -->
<?php require_once 'public/layouts/nav.php' ?>
<!-- 页面主体内容 -->
<div class="container">
<!-- 表单部分(略) -->
</div><!-- /.container -->
<!-- 网页底部 -->
<?php require_once 'public/layouts/footer.php'; ?>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="public/js/check.js"></script>
</body>
</html>
上面用到了一个函数:require_once ,那就有必要了解一下 require、require_once、include、include_once 的区别。
require: 和 include 几乎完全一样,除了处理失败的方式不同之外。require 在出错时产生 E_COMPILE_ERROR 级别的错误。换句话说将导致脚本中止而 include 只产生警告 E_WARNING),脚本会继续运行。
require_once:和 require 语句完全相同,唯一区别是 PHP 会检查该文件是否已经被包含过,如果是则不会再次包含。
include:同上 require。
include_once :在脚本执行期间包含并运行指定文件。此行为和 include 语句类似,唯一区别是如果该文件中已经被包含过,则不会再次包含。如同此语句名字暗示的那样,只会包含一次。
再次打开网页,你会发现没有任何变化。说明我们的操作是成功的。
2.2 建立用户主页
我们往往更希望把用户的主页作为 index.php
,那我们就把之前那个首页文件重命名为 welcome.php
作为欢迎界面。新建一个 index.php
文件作为用户主页。我们还是可以沿用 welcome.php
的风格样式。所以,把 2.1 中的 index.php
的代码复制到现在的 index.php
中,把表单部分去掉,添加用户首页需要展示的内容:
<?php
session_start(); //开启session会话
//此处添加PHP代码
?>
<!DOCTYPE html>
***
***
<!-- 页面主体内容 -->
<div class="container">
<div class="content">
<div class="starter-template">
<!-- 这里做了修改,其他地方自由发挥 -->
<h1>Welcome To ShiYanLou</h1>
<div class="jumbotron">
<!-- 打印用户名 -->
<h1>Hello, <?php echo $_SESSION['user']; ?>!</h1>
<p>This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.</p>
<p><a class="btn btn-primary btn-lg" href="http://www.shiyanlou.com" role="button">Learn more</a></p>
</div>
</div>
</div>
</div><!-- /.container -->
这里我在主体内容中使用了 bootstrap 中的 巨幕 组件,并将登录用户的用户名打印出来,由于使用了 session ,所以我们需要在顶部首先开启 session:
2.3 浏览限制与细节处理
index.php
作为我们的用户主页,应该只能允许已登录的当前用户查看。如果用户未登陆,我们应该将其跳转到 welcome.php
让用户注册或登陆。如果用户已经登陆的,那么只能让他进入主页中去,而不能让他再次进入 welcome.php
中去登陆或者注册。因此我们需要对用户做一些浏览限制:
在 index.php
顶部的 php 代码段单继续添加如下代码:
//未登录,跳转至欢迎界面
if (!isset($_SESSION['user'])) {
header('location:welcome.php');
exit(); //防止继续执行
}
在 welcome.php 顶部添加 php 代码:
<?php
session_start(); //首先要开始 session
//已登录,跳转至主页
if (isset($_SESSION['user'])) {
header('location:index.php');
exit();
}
?>
细心的你可能已经注意到了,在我们的用户主页的导航栏上,还有 register 和 login 的按钮,这是不应该在主页上出现的。所以我们需要修改导航栏部分的展示效果,编辑 /public/layouts/nav.php
:
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Menu</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">ShiYanLou</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Home</a></li>
<?php
if (!isset($_SESSION['user'])) {
?>
<li><a href="#Register" data-toggle="modal" data-target="#register">Register</a></li>
<li><a href="#Register" data-toggle="modal" data-target="#login">Login</a></li>
<?php
}else{
?>
<li><a href="http://www.shiyanlou.com" >Learn</a></li>
<li><a href="admin/Logout.php" >Logout</a></li>
<?php
}
?>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
我在上面的导航栏部分,添加了判断条件,如果已经登陆进入了用户主页,则像是 Learn 和 Logout 按钮。否则用户现在处于欢迎界面,就应该显示 Register 和 Login 按钮。
这里需要使用登出的方法,所以我们现在应该在 admin 新建一个 Logout.php
文件来完成登出的功能。
Logout.php
:
<?php
session_start();
unset($_SESSION['user']);
echo "<script>alert('You hava logouted!');location.href = '/welcome.php'</script>";
现在,我们的细节和浏览限制已经完成了。如果你还觉得有什么不足之处,你可以继续完善。
三、实现记住我功能
我们经常在登陆的时候会看到这个选项,使用这个选项,只要不清除浏览器数据,下次访问网站时可以自动登陆,这是非常方便的一个功能。之所以这个功能放到这里来实现,是因为这个选项不是必须的,对于一些对安全要求比较高的网站,是不提供这个功能。比如淘宝等。使用 cookie 实现自动登录具有一定的安全风险,如果在真实的项目中对 cookie 的处理一定要谨慎,对于一般的网站则不需要考虑太多。我们之前实现的那些功能都是比较通用的。接下来我们可以把自动登录的功能加入到我们的项目中。
-
首先,在登陆表单添加
Remember Me
选项(默认 yes):<div class="form-group"> <label for="password" class="col-sm-4 control-label">Remember Me:</label> <div class="col-sm-3"> <label class="checkbox-inline"> <input type="radio" name="rem" id="yes" value="1" checked> Yes </label> <label class="checkbox-inline"> <input type="radio" name="rem" id="no" value="0"> No </label> </div> </div>
-
其次,修改后台登陆处理程序:
private $rem; //添加记住我私有属性 ***** $this->rem = $_POST['rem']; //构造方法中获取记住我参数 //在登陆成功之后,跳转页面之前添加判断,若 记住我,则将标识保存到session中 if ($this->rem == 1) { $_SESSION['rem'] = '1'; }
这里可能有人会有疑惑,为什么不在这里直接使用 setcookie() 函数,而是保存到session中。如果你在这里设置了cookie,打开浏览器,使用开发者工具查看网络请求,你就会发现,从登陆成功再到跳转至用户主页的过程中,访问
index.php
的请求header
部分中的Request Headers
中包含了你刚才设置的 cookie ,而不是在Response Header
中,很明显,当我们关闭了浏览器,这个 cookie 就不存在。更多的关于response cookie
和request cookie
的区别,可以到网上去查阅相关的资料。 -
生成 cookie 并自动登陆:
修改
index.php
上方 php 代码:if (!isset($_SESSION['user'])) { //未登录 if (isset($_COOKIE['user'])) { //是否存在 cookie $_SESSION['user'] = $_COOKIE['user']; //存在,自动登陆 }else{ header('location:welcome.php'); //不存在,跳转至欢迎界面 } } if (isset($_SESSION['rem'])) { //如果 session 中有 记住我 的标识,则在本页面生成用户名的 cookie,有效时间为一个小时(可以调节) setcookie('user',$_SESSION['user'],time()+3600); unset($_SESSION['rem']); //清除本条session }
-
清除 cookie :
既然上面生成了 cookie ,那么当我们进行登出操作时,就应该将其清理掉。所以在 Logout.php 中添加一句代码:
unset($_COOKIE['user']);
OK !现在我们的项目已经实现了
记住我
这样一个功能。基本上完成了本次项目的全部功能。
四、实验总结
本课程通过四次实验操作,带领大家从页面制作到最后的功能完善,既学到了前端的知识,也对后端技术有了一定的了解。这也是成为一名合格的PHP程序员所必须掌握的本领。相信通过本次课程的学习,大家以后自己搭建网站的时候,可以很轻松的实现用户注册登陆模块的功能。当然,因为作者的能力有限,文档中难免会有这样那样的不足之处,一些构思或者实现方法可能不是最优的,也欢迎各位在课程评论中指出。