一、概述
本节课是一个小的实战练习, 利用cookie和session实现用户登陆和验证,重点除了cookie和session以外还要理解业务逻辑。
二、作业
1、cookie和session优缺点分析
Cookie的优缺点:
优点:极高的扩展性和可用性
通过良好的编程,控制保存在cookie中的session对象的大小。
通过加密和安全传输技术(SSL),减少cookie被破解的可能性。
只在cookie中存放不敏感数据,即使被盗也不会有重大损失。
控制cookie的生命期,使之不会永远有效。偷盗者很可能拿到一个过期的cookie。
缺点:
Cookie数量和长度的限制。每个domain最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。
安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。即使加密也与事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。
有些状态不可能保存在kh端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在kh端,那么它起不到任何作用。
Session的优缺点:
优点
如果要在诸多Web页间传递一个变量,那么用Session变量要比通过QueryString传递变量可使问题简化。
要使WEb站点具有用户化,可以考虑使用Session变量。你的站点的每位访问者都有用户化的经验,基于此,随着LDAP和诸如MS Site
Server等的使用,已不必再将所有用户化过程置入Session变量了,而这个用户化是取决于用户喜好的。
你可以在任何想要使用的时候直接使用session变量,而不必事先声明它,这种方式接近于在VB中变量的使用。使用完毕后,也不必考虑将其释放,因为它将自动释放。
缺点
Session变量和cookies是同一类型的。如果某用户将浏览器设置为不兼容任何cookie,那么该用户就无法使用这个Session变量!
当一个用户访问某页面时,每个Session变量的运行环境便自动生成,这些Session变量可在用户离开该页面后仍保留20分钟!(事实上,这些变量一直可保留至“timeout”。“timeout”的时间长短由Web服务器管理员设定。一些站点上的变量仅维持了3分钟,一些则为10分钟,还有一些则保留至默认值20分钟。)所以,如果在Session中置入了较大的对象(如ADO
recordsets,connections, 等等),那就有麻烦了!随着站点访问量的增大,服务器将会因此而无法正常运行!
因为创建Session变量有很大的随意性,可随时调用,不需要开发者做精确地处理,所以,过度使用session变量将会导致代码不可读而且不好维护。
虽然“你可以在任何想要使用的时候直接使用session变量,而不必事先声明它,这种方式接近于在VB中变量的使用。使用完毕后,也不必考虑将其释放,因为它将自动释放”。但是,“谁”想到那儿呢?变量的含义是什么?这些都变得不很清晰。
2、cookie部分
./inc/heade.php
实例
<!--inc文件夹including--> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <?php echo isset($page_title) ? $page_title : '<h3>没有标题</h3>'; ?> </body> </html>
./inc/footer.php
实例
<?php $page_title = '<hr><h3>这里是底部</h3>'; include 'header.php';
./inc/function.php
实例
<?php /** * 公共函数部分 */ //当用户登陆成功以后的跳转$page='xxxx.php'; function redirect_user($page = '../index.php'){ $url = 'http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']); $url = rtrim($url. '/\\'); $url .= '/'.$page; header('Location:' .$url); exit(); } //验证用户登录 //function check_login($dbc, $email='', $password) function check_login($dbc, $email='', $password){ //初始化错误数组 $errors = []; //非空 if (empty($email)){ $errors[] = '邮箱不能为空'; return[false,$errors]; }else{ $e = mysqli_real_escape_string($dbc,trim($email)); } if (empty($password)){ $errors[] = '密码不能为空'; return[false,$errors]; }else{ $p = mysqli_real_escape_string($dbc,trim($password)); } //表中数据验证,$row得到的user_id 和user_name if (empty($errors)){ $sql = "SELECT `user_id`,`user_name` FROM `user` WHERE `email` = '$e' AND `password` = sha1('$p')"; //执行 $res = mysqli_query($dbc,$sql); if (mysqli_num_rows($res) == 1){ $row = mysqli_fetch_array($res,MYSQLI_ASSOC); return [true,$row]; }else{ $errors[] = '邮箱或者密码不正确'; } return[false,$errors]; } }
./inc/connnect.php
实例
<?php /** * 数据库连接,面向过程方法 * die() 函数输出一条消息,并退出当前脚本。该函数是 exit() 函数的别名。 */ $dbc = mysqli_connect('127.0.0.1','root','root','php'); if (mysqli_connect_errno()){ die('连接失败'.mysqli_connect_error()); } $dbc->set_charset('utf8');
index.php
实例
<?php include 'inc/header.php'; echo '<h2 style="color:red">首页</h2>'; if (isset($_COOKIE['id'])){ echo '<p>学号:'.$_COOKIE['id'].'<br>姓名:'.$_COOKIE['name'].'</p><a href="logout.php">退出登陆</a>'; }else{ echo '<a href = "login.php">游客请登陆</a>'; } include 'inc/footer.php';
login.php
实例
<?php /** * 对登陆页面(login_page)的数据进行数据验证(通过function里面的方法), * 成功后跳转到logged in欢迎页面。 */ if ($_SERVER['REQUEST_METHOD'] == 'POST') { require './inc/function.php'; require './inc/connect.php'; //check_login函数返回两个值,一个布尔值(true/false),一个数组。 list($check, $data) = check_login($dbc, $_POST['email'], $_POST['password']); //检测是否通过验证,if(true) if ($check == true) { setcookie('id', $data['user_id']); setcookie('name', $data['user_name']); redirect_user('loggedin.php'); } else $errors = $data; mysqli_close($dbc); } include 'login_page.php';
loggedin.php
实例
<?php /*登陆成功界面*/ //判断是否登陆 if (!isset($_COOKIE['id'])){ require './inc/function.php'; redirect_user(); } $page_title = '登陆成功'; include './inc/header.php'; //heredoc?????? echo <<< "WELCOME" <h2 style = "color:red">登陆成功</h2> <p>欢迎你{$_COOKIE['name']}</p> <p><a href="index.php">首页</a> </p> <p><a href="logout.php">退出</a> </p> WELCOME; include './inc/footer.php';
login_page.php
实例
<?php /** * 登陆页面 */ $page_title = '用户登陆'; include './inc/header.php'; if (isset($errors) && !empty($errors)){ $errors_msg = '<p style="color: coral">'; foreach ($errors as $msg){ $errors_msg .= $msg.'<br>'; } echo $errors_msg.'</p>'; } ?> <h2 style="color: coral">用户登录</h2> <form action="login.php" method="post"> <p> <label for="email">邮箱</label> <input type="email" name="email" id="email" value="<?php echo isset($_POST['email'])?$_POST['email']:'' ?>"> </p> <p> <label for="password">密码</label> <input type="password" name="password" id="password" value="<?php echo isset($_POST['passwor'])?$_POST['password']:'' ?>"> </p> <p> <button type="submit" name="submit" id="submit">登陆</button> </p> </form> <?php include './inc/footer.php';
logout.php
实例
<?php /** * 登出 */ //判断是否登陆,未登录的话转到function.php使用redirect_user();默认值是index.php再转到登陆界面 if (!isset($_COOKIE['id'])){ require './inc/function.php'; redirect_user(); }else{ setcookie('id','',time()-3600); setcookie('name','',time()-3600); } $page_title = '退出登陆'; include './inc/header.php'; echo <<< "BYE" <h2 style="color:red">退出成功</h2> <p><a href="login.php">登录</a></p> BYE; include './inc/footer.php';
结果图:
2、session部分
(1)启用session在文件开始加入代码:session_start();
(2)session部分的主体代码与cookie的一致。将cookie改为session即可
(3)session的清除与cookie不同:
session_destroy();//清除服务器session
setcookie('PHPSESSID','',time()-3600);
运行区别截图:
三、总结
1、登陆页面(login_page)数据进行数据验证(通过function里面的方法),成功后跳转到logged in欢迎页面。登出界面判断是否登陆,未登录的话转到function.php使用redirect_user();默认值是index.php再转到登陆界面。
2、check_login函数返回两个值,一个布尔值(true/false),一个数组。
3、$_COOKIE['id']写错为$COOKIE['id']
4、die() 函数输出一条消息,并退出当前脚本。该函数是 exit() 函数的别名。
5、表中数据验证,$row数组中的键名是由sql语句得到的user_id 和user_name,也就是数据库里面的名字。