现在的位置: 首页 > 综合 > 正文

PHP cookie和session的分析

2013年08月11日 ⁄ 综合 ⁄ 共 5918字 ⁄ 字号 评论关闭
PHP cookie和session的分析

 

cmpan(at)qq.com
流水孟春
lib.cublog.cn

转载请注

1.

PHP



COOKIE

cookie
是一种在远程浏览器端储存数据并以此来跟踪和识别用户的机制。

PHP


http
协议的头信息里发送
cookie,

因此
setcookie()
函数必须在其它信息被输出到浏览器前调用,这和对
header()
函数的限制类似。

1.1

设置

cookie
:


   

可以用
setcookie()

setrawcookie()
函数来设置
cookie
。也可以通过向客户端直接发送
http
头来设置
.
1.1.1


使用

setcookie()

函数

设置cookie:


bool
setcookie ( string name [, string value [, int expire [, string path [,
string domain [, 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 ( callback open, callback close, callback read, callback write, callback destroy, callback gc )
就是提供给我们解决这个问题的方案
.




该函数使用的
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
关联文件


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


2.7 session

安全问题



攻击者通过投入很大的精力尝试获得现有用户的有效会话
ID,
有了会话
id,
他们就有可能能够在系统中拥有与此用户相同的能力
.

因此
,
我们主要解决的思路是效验
session ID
的有效性
.

<
?
php

抱歉!评论已关闭.