PHP实战之Cookie会话控制

本文深入探讨了PHP中的Cookie使用,包括Cookie的概念、应用场景、操作方法、实战自动登录效果以及Cookie类的封装。同时,介绍了localStorage的基础用法,比较了它与Cookie的优缺点,并展示了如何扩展localStorage实现数组存储和过期时间功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#程序员薪资揭榜#你做程序员几年了?月薪多少?发量还在么?>>> hot3.png

 

1.前言

cookie是个比较重要的知识点,下面我们一曲来回顾一下它。

 

2.HTTP协议简介及原理

2.1会话控制简介及HTTP浅析

HTTP最大特点是无连接无状态的

up-243a06ff46fc137025c6bbade325dd9297d.png

up-fbc2b12b9657b9c2fbb27157a5af7619ffe.png

3. COOKIE的使用

3.1 Cookie简介

cookie保存在客户端中,又分为内存cookie和硬盘cookie;其中内存cookie是由浏览器来维护,保存在内存中,浏览器关闭后就消失了,存在时间短暂;而硬盘cookie保存在硬盘中,有一个过期时间,除非用户手动清除或者到了过期时间,硬盘cookie不会被删除,其存在时间是长期的。

3.2 cookie使用场景

登录状态、购物车等

3.2.1操作cookie思维导图

up-3c8610482e7f93c8543e954b7c1bb76aef9.png

3.2.2操作cookie代码

<?php
//第二个参数,这是内存cookie,浏览器关闭之后数据就消失
setcookie('username','fangzhijie');
//第三个参数,设置cookie时间
setcookie('checklogin','1',time()+30);
//第四个参数,测试有效路径
setcookie('estPath1','test',time()+3600,'/');//在根目录下有效

//第五个参数,在二级域名或者三级域名使用cookie
setcookie('name1','name1',time()+3600,'/','mtdg.club');
//第六个参数,是否只能在https下运行设置cookie成功
setcookie('secure1','secure1',time()+3600,'/','',true);
setcookie('secure2','secure2',time()+3600,'/','',false);

3.2.3 setrawcookie的使用

该函数类似setcookie()函数,但它不会对值进行urlencode()编码

3.2.4更新和删除Cookie的操作

//更新cookie
setcookie('username','king',time()+3600);
setcookie('username','king123',time()+3600);

//删除cookie

在php中使用“setcookie($cookiename, '');”或者“setcookie($cookiename, NULL);”都会删除cookie

PS:更新和删除cookie都需要保证名字($domain)相同且路径($path)一致才能正确修改或删除,否则路径不同,则会生成或删除不同的cookie,这是很容易犯的一个错误

3.2.5通过header函数设置Cookie

//通过header可以设置cookie
header('Set-Cookie:a=1');
//通过header可以加上过期时间,比如设定过期时间一小时
header('Set-Cookie:b=2;expires='.gmdate('D, d M Y H:i:s GMT',time()+3600));
///通过header指定有效路径
header('Set-Cookie:c=3;expires='.gmdate('D, d M Y H:i:s GMT',time()+3600).';domain=.phpfamily.org');
//通过header指定有效域
header('Set-Cookie:d=4;path=/test/a/');
//通过header指定安全(HTTPS)开启
header('Set-Cookie:d=4;secure');
//通过header指定HTTPOnly开启
header('Set-Cookie:d=4;httponly');

3.2.6 Cookie保存数组形式的数据

// Cookie保存数组形式的数据
setcookie('userInfo[username]','king',strtotime('+7 days'));
setcookie('userInfo[email]','747245429@qq.com',strtotime('+7 days'));
setcookie('userInfo[address]','dongguan',strtotime('+7 days'));

3.2.7通过JS实现操作Cookie

在浏览器编辑器Console内输入document.cookie就能获得cookie的值,如下图所示

up-914a6ee553cbf0e872523f2f5d026b9c939.png

也可以直接在Application中直接查看,通过JS代码操作COOKIE

<script>
    var Cookie={
        set:function(key,val,expiresDays){
            //判断是否设置了过期时间expiresDays
            if(expiresDays){
                var date=new Date();
                date.setTime(date.getTime()+expiresDays*24*3600*1000);//格式化时间
                var expiresStr="expires="+date.toGMTString()+';';
            }else {
                var expiresStr='';
            }
            document.cookie=key+'='+escape(val)+';'+expiresStr;
        },
        get:function(key){
            var getCookie=document.cookie.replace(/[ ]/g,'');
            var resArr=getCookie.split(';');
            var res;
            for(var i= 0,len=resArr.length;i<len;i++){
                var arr=resArr[i].split('=');
                if(arr[0]==key){
                    res=arr[1];
                    break;
                }
            }
            return unescape(res);
        }
    };
</script>

将上述JS代码粘贴到浏览器编辑器Console,回车执行JS代码,然后在设置如下cookie

up-b2b43b1b0823b6e4fb8c8d2aeec10a6d846.png

执行成功就能在Application查看到我们设置的cookie了

up-98557e0691edc65202bed6cf9ce26a9cdb6.png

然后我们获取一下刚刚设定的cookie,就能够获得key对应的value值,代码如下:

up-4be1c13e9ff825a283f3bd0df4d517e3951.png

3.3 Cookie实战之自动登陆效果

3.3.1简单的表单页面代码

<html>
<body>
<h1>登录页面</h1>
<form action="checklogin.php">
    <label for="username">用户名</label>
    <input type="text" name="username" id="username"placeholder="请输入姓名" >
    <label for="password">密码</label>
    <input type="password" name="password" id="password" placeholder="请输入密码">
    <div class="checkbox">
        <label>
            <input type="checkbox" name="autoLogin" value="1">一周内自动登录
        </label>
    </div>
    <button type="submit">立即登录</button>
</form>
</body>
</html>

3.3.2登录逻辑处理

<?php
$username=$_POST['username'];
$password=md5($_POST['password']);
$autoLogin=$_POST['autoLogin'];
//连接数据库
$link=mysqli_connect('localhost','root','root') or die('Connect Error');
mysqli_set_charset($link,'utf8');
mysqli_select_db($link,'test') or die('WITHOUT THIS DAABASE');
//根据姓名查询数据
$sql="select id,username,password from user where username={$username} and password={$password0}";
$sql=mysqli_escape_string($link,$sql);
$result=mysqli_query($link,$sql);
if(mysqli_num_rows($result)==1){
    //如果是记住登陆,则存入cookie
    if($autoLogin==1){
        $row=mysqli_fetch_assoc($result);
        setcookie('username',$username,strtotime('+7 days'));
        $salt='king';
        $auth=md5($username.$password.$salt).":".$row['id'];
        setcookie('auth',$auth,strtotime('+7 days'));
    }else{
        setcookie('username',$username);
    }
    exit("<script>alert('登陆成功~');location.href='index.php'</script>");
}

3.4 Cookie操作类的封装

<?php
/**
*Cookie的设置、读取、更新、删除
*/

class CustomCookie{
   static private $_instance = null;

   private $expire = 0;
   private $path = '';
   private $domain = '';
   private $secure = false;
   private $httponly = false;

   /**
   *构造函数完成Cookie参数初始化工作
   *@param [array] $options Cookie相关选项
   */
   private function __constrct(array $options = []){
      $this->setOptions($options);
   }

   /**
    * 设置相关选项
    * @param array $options Cookie相关选项
    * @return $this
    */
   private function setOptions(array $options = []){
   if(isset($options['expire'])){//是否设置cookie过期时间
      $this->expire = (int)$options['expire'];
   }

   if(isset($options['path'])){
      $this->path = $options['path'];
   }

   if(isset($options['domain'])){
      $this->domain = $options['domain'];
   }

   if(isset($options['secure'])){
      $this->secure = (bool)$options['secure'];
   }

   if(isset($options['httponly'])){
      $this->httponly = (bool)$options['httponly'];
   }
   return $this;
}

   /**
   *单例模式
   *@param [array] $options Cookie相关选项
   *@return object 对象实例
   */
   public static function getInstance(array $options = []){
      if(is_null(self::$_instance)){
         $class = __CLASS__;
         self::$_instance = new $class($options);
      }
      return self::$_instance;
   }

   /**
   *设置Cookie
   *@param string $name Cookie名
   *@param mixed $value Cookie值
   *@param array $options 其它选项
   *
   */
   public function set(string $name, $value, array $options = []){
      if(is_array($options)&&count($options)>0){
         $this->setOptions($options);
      }
      if(is_array($value) || is_object($value)){
         $value = json_encode($value, JSON_FORCE_OBJECT);
      }
      setCookie($name, $value, $this->expire, $this->domain, $this->secure, $this->httponly);
   }

   /**
   *获取Cookie
   *@param String $name Cookie名
   *@return mixed  返回一个null或者一个对象
   */
   public function get(string $name){
      if(isset($_COOKIE[$name])){
         return substr($_COOKIE[$name], 0, 1) == '{' ? json_decode($_COOKIE[$name]) : $_COOKIE[$name];
      }else{
         return null;
      }
   }
   /**
   *删除指定Cookie
   *@param string $name COOKIE名称
   *@param array $options 相关选项
   */
   public function delete(string $name,array $options=[]){
      if(is_array($options)&&count($options)>0){
         $this->setOptions($options);
      }
      if(isset($_COOKIE[$name])){
         setcookie($name,'',time()-1,$this->path,$this->domain,$this->secure,$this->httponly);
         unset($_COOKIE[$name]);
      }
   }
   /**
   *删除所有COOKIE
   *@param array $options=[] 相关选项
   **/
   public function deleteAll(array $options=[]){
      if(is_array($options)&&count($options)>0){
         $this->setOptions($options);
      }
      foreach ($_COOKIE as $name => $value) {
         setcookie($name,'',time()-1,$this->path,$this->domain,$this->secure,$this->httponly);
         unset($_COOKIE[$name]);
      }
   }
}

//测试连接cookie类
$cookie = CustomCookie::getInstance();
var_dump($cookie);
//测试设置cookie
$cookie->set('aa', 11);
$cookie->set('bb', 22);
$cookie->set('cc', 33, ['expire'=>time()+3600])
$cookie->set('userInfo', ['username'=>'shulv', 'age'=>22]);
//测试得到cookie
var_dump($cookie->get('userInfo'));
var_dump($cookie->get('aa'));
//测试删除单个cookie
$cookie->delete('aa');
//测试删除所有cookie
$cookie->deleteAll();

4. localStorage的基本使用

4.1 cookie和localStorage的优缺点

cookie不是很安全,因此不要使用cookie存储敏感数据,黑客劫取cookie之后可以用来实现cookie欺骗;其次每个域名允许存储的cookie大小和数量是有限的,cookie保存最大字节数是4K,数量则根据不同浏览器而定,因此不要把cookie当做客户端存储器来使用;另外cookie设置之后每次都会附着在HTTP的头中一起发送,这样很浪费带宽资源。因此业界就cookie缺点发明了替代品:HTML5 的localStorage

up-3576d2b824508c7f6bd01016959cdaca56d.png

注意:localStorage只能存储字符串

4.2查看浏览器是否支持localStorage

if(window.localStorage){
    alert('支持');
}else{
    alert('不支持');
}

4.3 localStorage常用的API

  • 设置localStorage.setltem(key,value)
  • 读取localStorage.getitem(key)
  • 删除指定key localStorage.removeItem(key)
  • 全部删除 localStorage.clear()
  • 获取指定的键名 key(i)

4.4 localStorage取巧存数组

默认情况下只能存储字符串,如果需要存储数组,则需要转换,如下所示:

//定义变量

var userInfo={'username':'king','age':23,'email':'747245429@qq.com'};

//设置localStorage

localStorage.setItem('userInfo',JSON.stringify(userInfo))

//读取localStorage

localStorage.getItem('userInfo')

//格式化为数组输出localStorage

JSON.parse(localStorage.getItem('userInfo'))

up-bb68e7ad444cf1b9e2870a6569224de274e.png

4.5自己写localStorage扩展

4.5.1 扩展之封装get和set

自己写一个localStorage的get和set扩展兼容数组,代码如下:

var Custom_localStorage={
set:function(key,value){
var item={
data:value
}
localStorage.setItem(key,JSON.stringify(item));
},
get:function(key){
var val=localStorage.getItem(key);
if(!val)return null;
val=JSON.parse(val);
return val;
}
};

将上述代码导入控制台,然后输入下面测试代码:

up-b449e7d900555b04c0bd5605d87c6d2645a.png

up-b8ed6720304f0c3bc823eaa3e97b1b1fbf8.png

up-3eac3c86e636eae653bf942c401ac47af35.png

4.5.2扩展之封装过期时间

添加过期时间功能,代码如下:

var Custom_localStorage={
//添加过期时间
set:function(key,value,days){
var item={
data:value,
endtime:new Date().getTime()+days*24*3600*1000
};
localStorage.setItem(key,JSON.stringify(item));
},
get:function(key){
var val=localStorage.getItem(key);
if(!val)return null;
val=JSON.parse(val);
if(new Date().getTime()>val.endTime){
val=null;
localStorage.removeItem(key);
}
return val.data;
},
remove:function(key){
localStorage.removeItem(key);
return null;
},
removeAll:function(){
localStorage.clear();
return null;
}
};

将上述代码导入控制台,然后输入下面测试代码:

up-f2c8b63804ddb633e82461bcd266120916f.png

5.总结

通过上述回顾,我们能够较好的温习了cookie的一些知识点,而涉及到三次握手/四次挥手的更底层的问题我们没有探讨,该篇仅从实用角度去回顾,当然下面我也会对http的通信原理和底层知识进行整理和回顾。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值