PHP-会话控制-Cookie
1.会话控制
我们浏览网页,主要是浏览器与服务器之间进行交互。浏览器发送请求-->服务器接受请求并处理,返回响应-->浏览器接受响应并处理呈现给用户。
浏览器与服务器之间的交互使用http协议,http协议是一个无状态协议。所谓无状态协议就是服务器不维护状态信息,也就是说服务器只管处理请求但是它不记住你是谁。
但是我们日常浏览网页时,登陆过一次之后跳转到该网站的其他网页时从没有见过需要重复登陆的吧。
服务器又是怎么认得你是谁的呢?
有人可能想到:可以通过url,跳转网页时将用户信息传递过去。这是一个方法,但过于繁琐,并非上策。
这些问题就是会话控制需要解决的。
2.Cookie
Cookie常用于会话控制,它的本质其实就是:服务器交给浏览器客户端保存的一段信息。
http协议对Cookie提供了良好的支持。
如果服务器希望浏览器保存一个Cookie,服务器会把Cookie的信息放入响应的头部传给浏览器。
而浏览器当再次访问同一台服务器时会自动把该该服务器之前传过来的Cookie通过请求头部传回去。
创建Cookie
setcookie('test','this is a cookie',time()+60*60);
创建一个名为test值为this is a cookie 的Cookie,第三个参数是过期时间,本例设置一个小时后过期。
注:Cookie实在http头中传给浏览器的,所以这段代码之前不能有任何的输出,一个空格也不行。
打开浏览器,就可以找到刚才设置的Cookie了
高级选项
setcookie('test','this is a cookie',time()+60*60,'/test','.example.com',1);
第三个参数默认为 '/' ,只要访问该服务器跟目录下的任何文件,浏览器都会把Cookie传回去,如果是'/test',那么只要访问test目录下的网页才会传Cookie。
使用Cookie
PHP中使用全局数组$_COOKIE,访问浏览器传回来的Cookie。
var_dump($_COOKIE);//打印出全部Cookie
结果如下:
设置一个二维数组的Cookie
setcookie('user[id]',1,time()+60*60); setcookie('user[name]','mike',time()+60*60); setcookie('user[address]','China',time()+60*60);
这样在本地还是分成三段Cookie保存:
可以像而数组那样访问
echo $_COOKIE['user']['id'];echo '<br>'; echo $_COOKIE['user']['name'];echo '<br>'; echo $_COOKIE['user']['address'];echo '<br>';
删除Cookie
setcookie('test'); setcookie('user[id]'); setcookie('user[name]'); setcookie('user[address]');
Cookie没有特殊的删除函数,删除它的本质是让他的时间过期,这里如果你为它们各设置一个早于当前时间的时间戳,结果是一样的。
3.实例
在apche根目录下创建一个testcookie目录,并创建一下文件
login.php
1 <?php 2 if(isset($_POST['tijiao'])) 3 { 4 $username=$_POST['username']; 5 $password=$_POST['password']; 6 try 7 { 8 $pdo=new PDO('mysql:host=localhost;dbname=example','root',''); 9 $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 10 $r=$pdo->query("SELECT * FROM user WHERE user='$username' AND password=md5('$password') "); 11 if($r->rowCount()) 12 { 13 setcookie('username',$username,time()+60*60*24); 14 setcookie('password',$password,time()+60*60*24); 15 16 header('location:locked.php'); 17 } 18 else 19 { 20 $message="登陆失败"; 21 } 22 } 23 catch(PDOException $e) 24 { 25 exit('数据库连接失败'.$e->getMessage()); 26 } 27 } 28 ?> 29 30 <!DOCTYPE html> 31 <html> 32 <head> 33 <meta charset="utf-8"> 34 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 35 </head> 36 <body> 37 <p><?php if(isset($message)) echo $message; ?></p> 38 <form action="login.php" method="post" accept-charset="utf-8"> 39 用户名 40 <input type="text" name="username" placeholder="请输入用户名" required="required"> 41 密码 42 <input type="password" name="password" placeholder="请输入密码" required="required"> 43 <input type="submit" name="tijiao" value="登陆"> 44 </form> 45 </body> 46 </html>
lock.php
1 <?php 2 if(isset($_COOKIE['username'])&&isset($_COOKIE['password'])) 3 { 4 $username=$_COOKIE['username']; 5 $password=$_COOKIE['password']; 6 try 7 { 8 $pdo=new PDO('mysql:host=localhost;dbname=example','root',''); 9 $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 10 $r=$pdo->query("SELECT * FROM user WHERE user='$username' AND password=md5('$password') "); 11 if(!$r->rowCount()) 12 { 13 header('location:login.php'); 14 } 15 16 } 17 catch(PDOException $e) 18 { 19 exit('数据库连接失败'.$e->getMessage()); 20 } 21 } 22 else 23 { 24 header('location:login.php'); 25 } 26 ?>
logout.php
1 <?php 2 setcookie('username'); 3 setcookie('password'); 4 header('location:index.php'); 5 ?>
这样做也可以实现会话的控制,但是这样做弊端是很大的。
比如:用户名和密码保存在客户端,这样很不安全,一旦有人打开了保存Cookie的目录,那么用户的信息全部泄露。
因为cookie保存在客户端,用户可以很方便的更改它,服务器没法保证cookie里面信息的可靠性,所以每次验证的时候都要连接一次数据库,这样很麻烦。
这些问题就要在下一话的session中解决。