1.作业要求
用cookie和session分别实现登录与注册验证
2.作业分析
2.1流程图
2.2分析
2.2.1页面分析
-作业的显示页面为三个,一个是主页有登录和注册入口,一个是登录页面,一个是注册页面。除了显示的三个页面外,还需要一个控制分发的脚本。
-从流程图中可以看见:
未登录主页有两个出口一个是登录,一个是注册;
已登录主页有一个出口就是退出;
登录有两个出口一个是登录主页,一个是转向注册页;
注册有两个出口一个是注册主页,一个是转向登录页;
其中除了登录与注册页之间的相互跳转外,其余均应通过控制分发脚本进行处理并分发。
2.2.2数据流向
-登录页、注册页和主页退出均是通过$_GET 来传递参数供控制分发脚本进行判断。
-登录页、注册页表单中的数据均是通过$_POST来向控制分发脚本传递参数的。
-控制分发脚本处理完的参数在cookie方法中,是通过将数据序列化后存入$_COOKIE这个超全局变量中供主页调用的。
2.2.3分发控制页代码分析$users=[
['id'=>1,'email'=>'admin@php.cn','name'=>'admin','password'=>'8843028fefce50a6de50acdf064ded27'],
['id'=>2,'email'=>'peter@qq.cn','name'=>'peter','password'=>'5ba1a3fc5fa1363689baab6b3288def8'],
['id'=>3,'email'=>'dseven@php.cn','name'=>'dseven','password'=>'84d28f2183a9f2cf67b8b08f7652f757'],
];
以上代码是建立一个二维数组,用来模拟数据表,可以实验用户登录验证的数据,其中password字段是经过加密函数加密后的字符串。
$allowNames=['index.php','log.php','reg.php'];
$currentName=basename(filter_input(INPUT_SERVER,'HTTP_REFERER'));//变量中只有键名
if(!in_array($currentName,$allowNames)){
exit('非法来源');
}
以上代码是建立一个脚本白名单,并进行来源验证,主要是防止用户直接进入控制分发页,从流程图中可以看见能进入控制分发页的只有主页、登录页和注册页,将其三个放入一个数组中形成白名单,然后用请求页的$_SERVER['HTTP_REFERER']的值来进行判断。其中basename()的作用是将路径去掉,只保留脚本名。
$action=filter_input(INPUT_GET,'action',FILTER_SANITIZE_STRING);
$action=strtolower($action);
以上代码是分析整理用户通过$_GET传过来的参数,以供下部进行分发判断。
case'log':
if(filter_input(INPUT_SERVER,'REQUEST_METHOD')==='POST'){
$email=filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL);
$email=filter_var($email,FILTER_SANITIZE_EMAIL);
$password=md5(sha1(filter_input(INPUT_POST,'password')));
$results=array_filter($users,function($user)use($email,$password){
return$email===$user['email']&&$password===$user['password'];
});
if(count($results)===1){
setcookie('user',serialize(array_pop($results)));
exit('');
}else{
exit('');
}
}
break;
以上代码是switch($action)中的一个分支,主要是用来分析处理登录页面的数据。其基本步骤是:首先分析登录页面提交的数据是否通过POST方法传递,其次依次处理email和password的值,然后通过array_filter()和最开始建立的二维数组中的数据进行比对,第四步是将比对成功的数组的值序列化,并通过setcookie()写入COOKIE中,供主页调用。
case'reg':
$email=filter_var(filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL),FILTER_SANITIZE_EMAIL);
$password=md5(sha1(filter_input(INPUT_POST,'password1')));
$name=filter_input(INPUT_POST,'username',FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$id=4;
$data=compact('id','email','name','password');
$i=count($users);
if(array_push($users,$data)===$i+1){
setcookie('user',serialize(array_pop($users)));
exit('');
}
break;
以上代码是switch($action)中的一个分支,主要是用来分析处理注册页面的数据。其基本步骤是:首先用三个变量分别获取注册页面传来的三个值;其次是将三个值与ID值一起通过compact()组合成一个数组,将组合成的数组通过array_push()压入用户表信息二维数组中(注意此处只是演示,只能暂时压入,不会永久保留);第三步是将之前组合成的数组取值并进行序列化,然后通过setcookie()写入COOKIE中,供主页调用。此处需要注意的是:array_push()返回的是数组入栈后的总数量,而不是布尔值,因此不能用恒等于1来判断是否入栈成功,而要用整体数量是否加1来判断。
case'logout':
if(filter_input(INPUT_COOKIE,'user')){
setcookie('user',null,time()-3600);
exit('');
}
break;
以上代码,是用来处理主页退出登录的请求。关键点在于用setcookie()来注销掉之前建立的$_COOKIE[user],基本原理就是给它赋一个空值,并给一个过期时间,实际上只给过期时间也可以。
2.2.4主页代码分析<?php
if(filter_has_var(INPUT_COOKIE,'user')){
$user=unserialize(filter_input(INPUT_COOKIE,'user'));
}
?>
以上代码主要是用来,获取从控制分发页送至COOKIE的值。需要注意的是,在取值时要进行反序列化。
退出
登录
¦
注册
以上代码主要实现的是不同状态下主页显示不同的链接和信息。
3.重点和难点
3.1过滤器
-根据自己的理解其实过滤器应该是分为过滤函数和过滤器两类。其中filter_var()是属于过滤函数,FILTER_SANITIZE_EMAIL是属于过滤器也就是一种过滤规则,是过滤函数的一个参数。
个人感觉filter_var()如果加上合适的过滤器的话和filter_input()的效果基本一致,不过filter_var()不能直接从脚本外部获取输入并过滤,需要先建立一个变量并赋值之后才行。
3.2COOKIE与SESSION的理解
-感觉cookie就是浏览器中设立的一个容器,其他脚本都可以通过setcookie()来给里面装上东西,而且这个装好的东西不会随着安装脚本的消失而消失,它会一直保留在浏览器的容器中,这样别的脚本就能从中调用,达到不同脚本之间传递消息的功能。
-SESSION感觉像是比COOKIE更保密的容器,基本效果和作用都一样,不过用之前需要建立会话,用的过程中不需要过滤。
4.源代码
4.1主页源代码(cookie方法)<?php
if(filter_has_var(INPUT_COOKIE,'user')){
$user=unserialize(filter_input(INPUT_COOKIE,'user'));
}
?>
主页面首页
退出
登录
¦
注册