深入理解PHP中的Session和Cookie


Posted in PHP onJune 21, 2013

在一个页面设置一个cookie时,必须刷新或到下一个页面才可以用 $_COOKIE 得到变量的值.
原因是因为当页面第一次被浏览器访问载入时,页面中的 cookie 会被设置,将其发送存储到客户端指定的存储位置,所以$_COOKIE没有接收到客户端发送过来的 cookie 变量的值,当刷新或到下一个页面时,客户端会在页面程序在服务器端运行之前,发送与该地址相对应的 cookie到服务器端,所以 $_COOKIE 可以得到的值! 说白了就是当每一个页面被访问时,如果客户端找到了与访问地址相对应的 cookie 时,会在程序在服务器端运行之前发送这个 cookie 到服务器端. (个人对此的看法)
本人表达能力不强,如有不明,还请抱歉!

php中设置cookie数组的时候,不可以用像php中的那个添加数据的方法:

<?php
setcookie('my_cookie[]', 1);
setcookie('my_cookie[]', 2);
print_r($_COOKIE);    // Array ( [my_cookie] => Array ( [0] => 1 )) 
                      // 数组的值添加是添加成功了,不过索引没有变,后面的数据将前的数据覆盖了!
由此得到
       my_cookie[],默认指向数据的第一元素的位置,即索引为
0 的位置. 注意与php中的不一样! 以后用cookie数据记住要指定数组元素索引哦!$my_cookie[] = 1;
$my_cookie[] = 2;
print_r($my_cookie); //Array ( [0] => 1 [1] => 2) 
?>

删除 cookie 变量的两个方法:
1.php
<?php
setcookie('user_name_1', 'zhaofei299', time()+3600); // 生存期为 1 个小时
setcookie('user_name_2', 'ZHAOFEI299', time()+3600); // 生存期为 1 个小时
?>

2.php
<?php
setcookie('user_name_1');                // 第一种                
setcookie('user_name_2', "", time()-1); // 第二种
print_r($_COOKIE);                       // 刷新页面2下以上会输出 Array ( [user_name_1] => )/*为什么超级全局变量 $_COOKIE 中的 user_name_1 没有被删除(变量为空并不代表不存在),而
user_name_2被删除了? 那是因为两个删除变量的方式不同!
第一种: 是设置了 cookie 的生存期, 只不过是将它的值默认设置为空,生存期为与浏览器一样,浏览器
关闭时,cookie才会删除!所以当重新打开一个浏览器,输出地址时,才会发现 cookie 变量全部被删除了!
将2.php 中两个 setcookie() 函数部分注释掉看看(重新输出了地址)!
第二种: 也是设置了 cookie 的生存期,是使 cookie 的生存期一定过期, cookie 也就被删除,所以刷
新页面,客户端向服务器端发送 cookie 时, $_COOKIE 并没有能够得到该cookie变量的值!
*/
?>

会话id默认储放在客户端Cookie中!
<?php
session_start(); 
print_r($_COOKIE); 
?>

cookie的设置有两种方法
header('set-cookie:user=zhaofei299');
setcookie('user', 'zhaofei299');
会话变量不能被GET数据或POST数据重载!
使用session变量传递数组,对象时无需序列化!
使用session变量传递对象时,在调用session_start()之前,必须包含该对类对象的定义,反序列化
(serialize)也是如此!
删除单个会话变量可以使用unset($_SESSION['***']) 直接删除!
删除所有的会话变量不可以用unset($_SESSION),因为这样会将所有的会话信息删除,包含存储在COOKIE
中的PHPSESSID,也就是破坏了两个页面之间的会话联系,应该使用$_SESSION = array();
消除会话id,使页面之间失去联系!
session_destroy();
程序清单1.1
<?php
session_start();
header('content-type:text/html;charset=utf-8');
$_SESSION['a'] = 'a';
$_SESSION['b'] = 'b';
unset($_SESSION);        //测试后,再注释下看看
$_SESSION['user'] = 'zhaofei299';
echo 'SESSION_ID: '.session_id().'<br />';
echo '<a href="3.php" target="_blank">测试下</a>';
?>

<?php
session_start();
echo $_SESSION['user'];
echo session_id();         //会话变量改变了
?>

会话id(session_id)的两种方式传递:
1.cookie
2.url
因为默认session是基于cookie的,而cookie又是跟随http协议发送的,所以与cookie一样,在
session_start()之前不能有任何输出!
现在主要说一说第二种,通过 url 传递会话id
php中已经定义SID这个常量来得到 会话的id
sesssin_id 的使用!
<?php
session_start();
echo defined('SID')?'true':'false'; // true
echo SID; //什么也没有? 
?>

为什么SID的值会是null 呢?是它哪里有问题了?
原因是因为 session 默认是基于 cookie 的,而 SID 只有 session_id 通过 url
传递数据时才会被赋值!
在浏览器中将 cookie 禁用,你就会发现 SID 有了输出,而不是 null!
删除session
要三步实现.
<?php
session_destroy();                         // 第一步: 删除服务器端session文件,这使用 
setcookie(session_name(),'',time()-3600); // 第二步: 删除实际的session: 
$_SESSION = array();                       // 第三步: 删除$_SESSION全局变量数组
?>

大家都知道session变量是保存在服务器端的,也就是说session的变量会保存在服务器中一个目录中,我
们可以在php.ini中的session.save_path 那里可以找到session文件中保存的地址.

默认的session的生存期是浏览的关闭就结束,但要知道会话过期结束后,当打开页面session_start()会
判断会话id 是否存在,如果不存在就创建一个,否则将该会话id 的变量载入页面!因为过期session_id会
被创建一个新的,但它保存在服务器端的session文件并没有被删除(关闭浏览器,打开session文件保存
地看看),所以要用session_destory()函数清除会话id,并同时清除相应的会话文件,这样的话才能做到最
彻底的清除!

session_id 使用 url 传递session 变量数据时,因为session_start()开启会话时会判断会话id 是否存
在,如果不存在就创建一个,否则将该会话id 的变量载入页面!

而现在是使用url 来传递session_id,然而每一次 刷新/进入页面 都会生成一个会话id,所以页面之间就
不能得到在另一页面设置过的session_id 的变量,那么使用 session也就没什么意义了!

解决方法:在session_start()之前,手动设置页面的session_id,这样页面的就可以得到前一页中所设置的
session变量的,也就实现了会话的传递,如下代码可以说明!
//已禁用 cookie
1.php

<?php
session_start();
$_SESSION['user'] = 'zhaofei299';
echo '<a href="2.php?'.SID.'">下一页</a>'; 
?>

1.php的第4行代码也可以写成:echo '<a href="2.php">下一页</a>';
可以设置php.ini 中的 session.use_trans_sid 为1,这样当使用 url 传递会话 id 时,
浏览器会自动将 session_id 追加到 url 的后面!
就好像 在浏览器中 输入: www.baidu.com 一样,浏览器会自动将其更换成 http://www.baidu.com/

2.php

<?php
session_id($_GET['PHPSESSID']);   // 手动设置session_id,这种就可以使用前一个页面的
session_id 的变量了,也就实现了会话!
session_start(); 
print_r($_SESSION);
?>

常用session函数:
bool   session_start(void); 初始化session
bool   session_destroy(void): 删除服务器端session关联文件。
string session_id() 当前session的id
string session_name() 当前存取的session名称,也就是客户端保存session ID的cookie名称.默认
PHPSESSID。
array session_get_cookie_params() 与这个session相关联的session的细节.
string session_cache_limiter() 控制使用session的页面的客户端缓存
ini    session_cache_expire() 控制客户端缓存时间
bool   session_destroy()     删除服务器端保存session信息的文件
void   session_set_cookie_params ( int lifetime [, string path [, string domain [, bool
secure [, bool httponly]]]] )设置与这个session相关联的session的细节
bool session_set_save_handler ( callback open, callback close, callback read, callback
write, callback destroy, callback gc )定义处理session的函数,(不是使用默认的方式)
bool session_regenerate_id([bool delete_old_session]) 分配新的session id 

PHP 相关文章推荐
用PHP+MySql编写聊天室
Oct 09 PHP
php $_SERVER[&quot;REQUEST_URI&quot;]获取值的通用解决方法
Jun 21 PHP
非常好用的两个PHP函数 serialize()和unserialize()
Feb 04 PHP
PHP5中Cookie与 Session使用详解
Apr 30 PHP
深入探讨:Nginx 502 Bad Gateway错误的解决方法
Jun 03 PHP
基于PHP服务端图片生成缩略图的方法详解
Jun 20 PHP
Mac系统下使用brew搭建PHP(LNMP/LAMP)开发环境
Mar 03 PHP
php实现网页缓存的工具类分享
Jul 14 PHP
php实现可逆加密的方法
Aug 11 PHP
php文件上传的两种实现方法
Apr 04 PHP
总结PHP中数值计算的注意事项
Aug 14 PHP
PHP常用排序算法实例小结【基本排序,冒泡排序,快速排序,插入排序】
Feb 07 PHP
PHP 使用MySQL管理Session的回调函数详解
Jun 21 #PHP
解析PHP中一些可能会被忽略的问题
Jun 21 #PHP
关于PHP堆栈与列队的学习
Jun 21 #PHP
浅析PHP 按位与或 (^ 、&amp;)
Jun 21 #PHP
浅析PHP中Collection 类的设计
Jun 21 #PHP
解析PHP无限级分类方法及代码
Jun 21 #PHP
PHP 循环删除无限分类子节点的实现代码
Jun 21 #PHP
You might like
THINKPHP+JS实现缩放图片式截图的实现
2010/03/07 PHP
基于Linux调试工具strace与gdb的常用命令总结
2013/06/03 PHP
实例讲解如何在PHP的Yii框架中进行错误和异常处理
2016/03/17 PHP
基于jquery的地址栏射击游戏代码
2011/03/10 Javascript
js中方法重载如何实现?以及函数的参数问题
2013/08/01 Javascript
js判断60秒以及倒计时示例代码
2014/01/24 Javascript
js操作输入框中选择内容兼容IE及其他主流浏览器
2014/04/22 Javascript
js中数组排序sort方法的原理分析
2014/11/20 Javascript
js实现背景图片感应鼠标变化的方法
2015/02/28 Javascript
AngularJS入门教程之ng-checked 指令详解
2016/08/01 Javascript
jQuery获取file控件中图片的宽高与大小
2016/08/04 Javascript
jQuery实现级联下拉框实战(5)
2017/02/08 Javascript
bootstrap table单元格新增行并编辑
2017/05/19 Javascript
layui监听单元格编辑前后交互的例子
2019/09/16 Javascript
openlayers 3实现车辆轨迹回放
2020/09/24 Javascript
OpenLayers3实现鼠标移动显示坐标
2020/09/25 Javascript
使用 Python 获取 Linux 系统信息的代码
2014/07/13 Python
深入讨论Python函数的参数的默认值所引发的问题的原因
2015/03/30 Python
使用Python中的线程进行网络编程的入门教程
2015/04/15 Python
利用Python中的mock库对Python代码进行模拟测试
2015/04/16 Python
Python制作爬虫抓取美女图
2016/01/20 Python
python使用opencv进行人脸识别
2017/04/07 Python
在Django中输出matplotlib生成的图片方法
2018/05/24 Python
python取数作为临时极大值(极小值)的方法
2018/10/15 Python
Python利用pandas处理Excel数据的应用详解
2019/06/18 Python
pandas中read_csv、rolling、expanding用法详解
2020/04/21 Python
Python字符串格式化f-string多种功能实现
2020/05/07 Python
详解CSS3中@media的实际使用
2015/08/04 HTML / CSS
营销经理工作检讨书
2014/11/03 职场文书
催款函范本大全
2015/06/24 职场文书
寒假致家长的一封信
2015/10/10 职场文书
汉语拼音教学反思
2016/02/22 职场文书
导游词之铁岭象牙山
2019/12/06 职场文书
CSS3实现模糊背景的三种效果示例
2021/03/30 HTML / CSS
GitHub上77.9K的Axios项目有哪些值得借鉴的地方详析
2021/06/15 Javascript
JavaScript实现简单的音乐播放器
2022/08/14 Javascript