php session和cookie使用说明


Posted in PHP onApril 07, 2010

1. PHP的COOKIE

cookie 是一种在远程浏览器端储存数据并以此来跟踪和识别用户的机制。PHP在http协议的头信息里发送cookie, 因此setcookie() 函数必须在其它信息被输出到浏览器前调用,这和对header() 函数的限制类似。1.1 设置cookie:
可以用setcookie() 或setrawcookie() 函数来设置cookie。也可以通过向客户端直接发送http头来设置.
1.1.1 使用setcookie()函数设置cookie:
bool setcookie( stringname [, stringvalue [, int expire [, stringpath [, stringdomain [, bool secure [, bool httponly]]]]]] )
name: cookie变量名value: cookie变量的值expire: 有效期结束的时间,
path: 有效目录,
domain: 有效域名,顶级域唯一secure: 如果值为1,则cookie只能在https连接上有效,如果为默认值0,则http和https都可以.
例子:

<?php 
$value= 'something from somewhere'; 
setcookie("TestCookie", $value); 
/* 简单cookie设置*/setcookie("TestCookie", $value, time()+3600); /* 有效期1个小时*/setcookie("TestCookie", $value, time()+3600, "/~rasmus/", ".example.com", 1); /* 有效目录/~rasmus,有效域名example.com及其所有子域名*/ 
?>

设置多个cookie变量: setcookie('var[a]','value');用数组来表示变量,但他的下标不用引号.这样就可以用$_COOKIE[‘var'][‘a']来读取该COOKIE变量.

1.1.2. 使用header()设置cookie;
header("Set-Cookie: name=$value[;path=$path[;domain=xxx.com[; ]]");
后面的参数和上面列出setcookie函数的参数一样.
比如:

$value= 'something from somewhere'; 
header("Set-Cookie:name=$value");

1.2 Cookie的读取:

直接用php内置超级全局变量$_COOKIE就可以读取浏览器端的cookie.
上面例子中设置了cookie"TestCookie",现在我们来读取:

print$_COOKIE['TestCookie'];

COOKIE是不是被输出了?!

1.3 删除cookie
只需把有效时间设为小于当前时间, 和把值设置为空.例如:
setcookie("name","",time()-1);
用header()类似.

1.4 常见问题解决:

1) 用setcookie()时有错误提示,可能是因为调用setcookie()前面有输出或空格.也可能你的文档使从其他字符集转换过来,文档后面可能带有BOM签名(就是在文件内容添加一些隐藏的BOM字符).解决的办法就是使你的文档不出现这种情况.还有通过使用ob_start()函数有也能处理一点.
2) $_COOKIE受magic_quotes_gpc影响,可能自动转义3) 使用的时候,有必要测试用户是否支持cookie
<!--[if!supportLineBreakNewLine]-->

1.5 cookie工作机理:

有些学习者比较冲动,没心思把原理研究,所以我把它放后面.
a) 服务器通过随着响应发送一个http的Set-Cookie头,在客户机中设置一个cookie(多个cookie要多个头).
b) 客户端自动向服务器端发送一个http的cookie头,服务器接收读取.

HTTP/1.x 200 OK
X-Powered-By: PHP/5.2.1
Set-Cookie: TestCookie=something from somewhere; path=/
Expires: Thu, 19 Nov 2007 18:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-type: text/html

这一行实现了cookie功能,收到这行后Set-Cookie: TestCookie=something from somewhere; path=/
浏览器将在客户端的磁盘上创建一个cookie文件,并在里面写入:

TestCookie=something from somewhere;
这一行就是我们用setcookie('TestCookie','something from somewhere','/');的结果.也就是用header('Set-Cookie: TestCookie=something from somewhere; path=/');的结果.
<!--[endif]-->

2. PHP的Session

session使用过期时间设为0的cookie,并且将一个称为session ID的唯一标识符(一长串字符串),在服务器端同步生成一些session文件(可以自己定义session的保存类型),与用户机关联起来.web应用程序存贮与这些session相关的数据,并且让数据随着用户在页面之间传递.

访问网站的来客会被分配一个唯一的标识符,即所谓的会话ID。它要么存放在客户端的cookie,要么经由URL 传递。会话支持允许用户注册任意数目的变量并保留给各个请求使用。当来客访问网站时,PHP 会自动(如果session.auto_start 被设为1)或在用户请求时(由session_start() 明确调用或session_register() 暗中调用)检查请求中是否发送了特定的会话ID。如果是,则之前保存的环境就被重建。2.1 sessionID的传送2.1.1 通过cookie传送sessin ID

使用session_start()调用session,服务器端在生成session文件的同时,生成session ID哈希值和默认值为PHPSESSID的session name,并向客户端发送变量为(默认的是)PHPSESSID(session name),值为一个128位的哈希值.服务器端将通过该cookie与客户端进行交互.
session变量的值经php内部系列化后保存在服务器机器上的文本文件中,和客户端的变量名默认情况下为PHPSESSID的coolie进行对应交互.
即服务器自动发送了http头:header('Set-Cookie: session_name()=session_id(); path=/');
即setcookie(session_name(),session_id());
当从该页跳转到的新页面并调用session_start()后,PHP将检查与给定ID相关联的服务器端存贮的session数据,如果没找到,则新建一个数据集.

2.1.2 通过URL传送session ID
只有在用户禁止使用cookie的时候才用这种方法,因为浏览器cookie已经通用,为安全起见,可不用该方法.
<a href="p.php?<?php print session_name() ?>=<?php print session_id() ?>">xxx</a>,也可以通过POST来传递session值.

2.2 session基本用法实例

<?php 
// page1.php 
session_start(); 
echo'Welcome to page #1'; 
/* 创建session变量并给session变量赋值*/$_SESSION['favcolor'] = 'green'; 
$_SESSION['animal'] = 'cat'; 
$_SESSION['time'] = time(); // 如果客户端使用cookie,可直接传递session到page2.php 
echo'<br /><a href="page2.php">page 2</a>'; 
// 如果客户端禁用cookie 
echo'<br /><a href="page2.php?' . SID . '">page 2</a>'; 
/* 
默认php5.2.1下,SID只有在cookie被写入的同时才会有值,如果该session 
对应的cookie已经存在,那么SID将为(未定义)空*/ 
?> 
<?php 
// page2.php 
session_start(); 
print$_SESSION['animal']; // 打印出单个session 
var_dump($_SESSION); // 打印出page1.php传过来的session值 
?>

2.3 使用session函数控制页面缓存.
很多情况下,我们要确定我们的网页是否在客户端缓存,或要设置缓存的有效时间,比如我们的网页上有些敏感内容并且要登录才能查看,如果缓存到本地了,可以直接打开本地的缓存就可以不登录而浏览到网页了.

使用session_cache_limiter('private');可以控制页面客户端缓存,必须在session_start()之前调用.
更多参数见http://blog.chinaunix.net/u/27731/showart.php?id=258087的客户端缓存控制.
控制客户端缓存时间用session_cache_expire(int);单位(s).也要在session_start()前调用.

这只是使用session的情况下控制缓存的方法,我们还可以在header()中控制控制页面的缓存.

2.4 删除session

要三步实现.
<?php
session_destroy(); // 第一步: 删除服务器端session文件,这使用setcookie(session_name(),'',time()-3600); // 第二步: 删除实际的session:
$_SESSION= array(); // 第三步: 删除$_SESSION全局变量数组?>

2.5 session在PHP大型web应用中的使用对于访问量大的站点,用默认的session存贮方式并不适合,目前最优的方法是用数据库存取session.这时,函数bool session_set_save_handler( callbackopen, callbackclose, callbackread, callbackwrite, callbackdestroy, callbackgc )就是提供给我们解决这个问题的方案.
该函数使用的6个函数如下:

1. bool open() 用来打开会话存储机制,

2. bool close() 关闭会话存储操作.

3. mixde read() 从存储中装在session数据时使用这个函数4. bool write() 将给定session ID的所有数据写到存储中5. bool destroy() 破坏与指定的会话ID相关联的数据6. bool gc() 对存储系统中的数据进行垃圾收集例子见php手册session_set_save_handler() 函数.
如果用类来处理,用session_set_save_handler(
array('className','open'),
array('className','close'),
array('className','read'),
array('className','write'),
array('className','destroy'),
array('className','gc'),
)
调用className类中的6个静态方法.className可以换对象就不用调用静态方法,但是用静态成员不用生成对象,性能更好.

2.6 常用session函数:

bool session_start(void); 初始化session
bool session_destroy(void): 删除服务器端session关联文件。stringsession_id() 当前session的id
stringsession_name() 当前存取的session名称,也就是客户端保存session ID的cookie名称.默认PHPSESSID。arraysession_get_cookie_params() 与这个session相关联的session的细节.
stringsession_cache_limiter() 控制使用session的页面的客户端缓存ini session_cache_expire() 控制客户端缓存时间bool session_destroy() 删除服务器端保存session信息的文件void session_set_cookie_params( int lifetime [, stringpath [, stringdomain [, bool secure [, bool httponly]]]] )设置与这个session相关联的session的细节bool session_set_save_handler( callbackopen, callbackclose, callbackread, callbackwrite, callbackdestroy, callbackgc )定义处理session的函数,(不是使用默认的方式)
bool session_regenerate_id([bool delete_old_session]) 分配新的session id

2.7 session安全问题攻击者通过投入很大的精力尝试获得现有用户的有效会话ID,有了会话id,他们就有可能能够在系统中拥有与此用户相同的能力.
因此,我们主要解决的思路是效验session ID的有效性.
<?php

if(!isset($_SESSION['user_agent'])){
$_SESSION['user_agent'] = $_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_USER_AGENT'];
}

/* 如果用户session ID是伪造*/elseif($_SESSION['user_agent'] != $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']) {
session_regenerate_id();
}
?>

2.8 Session通过cookie传递和通过SID传递的不同:
在php5.2.1的session的默认配置的情况下,当生成session的同时,服务器端将在发送header set-cookie同时生成预定义超级全局变量SID(也就是说,写入cookie和抛出SID是等价的.),当$_COOKIE['PHPSESSID']存在以后,将不再写入cookie,也不再生成超级全局变量SID,此时,SID将是空的.

2.9 session使用实例<?php
/**
* 效验session的合法性*
*/functionsessionVerify() {
if(!isset($_SESSION['user_agent'])){
$_SESSION['user_agent'] = MD5($_SERVER['REMOTE_ADDR']
.$_SERVER['HTTP_USER_AGENT']);
}
/* 如果用户session ID是伪造,则重新分配session ID */elseif($_SESSION['user_agent'] != MD5($_SERVER['REMOTE_ADDR']
. $_SERVER['HTTP_USER_AGENT'])) {
session_regenerate_id();
}
}

/**
* 销毁session
* 三步完美实现,不可漏*
*/functionsessionDestroy() {
session_destroy();
setcookie(session_name(),'',time()-3600);
$_SESSION= array();
}
?>

注明:

session 出现头信息已经发出的原因与cookie一样.
在php5中,所有php session 的注册表配置选项都是编程时可配置的,一般情况下,我们是不用修改其配置的.要了解php的session注册表配置选项,请参考手册的Session 会话处理函数处.
session的保存数据的时候,是通过系列化$_SESSION数组来存贮,所以有系列化所拥有的问题,可能有特殊字符的值要用base64_encode函数编码,读取的时候再用base64_decode解码

PHP 相关文章推荐
PHP执行linux系统命令的常用函数使用说明
Apr 27 PHP
PHP 事务处理数据实现代码
May 13 PHP
php中用foreach来操作数组的代码
Jul 17 PHP
让PHP更快的提供文件下载的代码
Jun 13 PHP
关于php操作mysql执行数据库查询的一些常用操作汇总
Jun 24 PHP
PHP5.3安装Zend Guard Loader图文教程
Sep 29 PHP
详解PHP数组赋值方法
Nov 07 PHP
PHP使用preg_split()分割特殊字符(元字符等)的方法分析
Feb 04 PHP
mac os快速切换多个PHP版本的方法
Mar 07 PHP
php实现不通过扩展名准确判断文件类型的方法【finfo_file方法与二进制流】
Apr 18 PHP
PHP保留两位小数的几种方法
Jul 24 PHP
PHP解决高并发问题
Apr 01 PHP
DedeCMS dede_channeltype表字段注释
Apr 07 #PHP
php抓取https的内容的代码
Apr 06 #PHP
php中几种常见安全设置详解
Apr 06 #PHP
PHP 检查扩展库或函数是否可用的代码
Apr 06 #PHP
php下关于中英数字混排的字符串分割问题
Apr 06 #PHP
Blitz templates 最快的PHP模板引擎
Apr 06 #PHP
PHP数组内存耗用太多问题的解决方法
Apr 05 #PHP
You might like
php中将数组转成字符串并保存到数据库中的函数代码
2013/09/29 PHP
windows7下安装php的imagick和imagemagick扩展教程
2014/07/04 PHP
PHP面向对象程序设计组合模式与装饰模式详解
2016/12/02 PHP
浅谈laravel数据库查询返回的数据形式
2019/10/21 PHP
Js之软键盘实现(js源码)
2007/01/30 Javascript
弹出广告特效(一个IP只弹出一次)的代码
2007/07/27 Javascript
Jquery中dialog属性小记
2010/09/03 Javascript
javascript动态加载二
2012/08/22 Javascript
Js(JavaScript)中,弹出是或否的选择框示例(confirm用法的实例分析)
2013/07/09 Javascript
jQuery插件jquery-barcode实现条码打印的方法
2015/11/25 Javascript
js计算时间差代码【包括计算,天,时,分,秒】
2016/04/26 Javascript
JS在浏览器中解析Base64编码图像
2017/02/09 Javascript
Vue表单验证插件的制作过程
2017/04/01 Javascript
vue基础之data存储数据及v-for循环用法示例
2019/03/08 Javascript
jQuery HTML获取内容和属性操作实例分析
2020/05/20 jQuery
vue用elementui写form表单时,在label里添加空格操作
2020/08/13 Javascript
[02:06]DOTA2英雄基础教程 暗影萨满
2013/12/16 DOTA
[02:23]完美世界全国高校联赛街访DOTA2第一期
2019/11/28 DOTA
Python中的tuple元组详细介绍
2015/02/02 Python
分析Python的Django框架的运行方式及处理流程
2015/04/08 Python
python中使用ctypes调用so传参设置遇到的问题及解决方法
2019/06/19 Python
python实现两个字典合并,两个list合并
2019/12/02 Python
python标识符命名规范原理解析
2020/01/10 Python
Pytorch自己加载单通道图片用作数据集训练的实例
2020/01/18 Python
Python如何访问字符串中的值
2020/02/09 Python
pycharm 更改创建文件默认路径的操作
2020/02/15 Python
CHARLES & KEITH英国官网:新加坡时尚品牌
2018/07/04 全球购物
漫威玩具服装及周边商品官方购物网站:Marvel Shop
2019/05/11 全球购物
贪睡宠物用品:Snoozer Pet Products
2020/02/04 全球购物
创业计划实施的7大步骤
2014/02/05 职场文书
安全生产先进个人材料
2014/02/06 职场文书
销售职业生涯规划范文
2014/03/14 职场文书
2014班子“三严三实”对照检查材料思想汇报
2014/09/18 职场文书
2014年帮扶工作总结
2014/11/26 职场文书
初中中等生评语
2014/12/29 职场文书
纪检监察立案决定书
2015/06/24 职场文书