cookie的工作流程:
客户端访问服务器,服务器调用response.addCookie()方法,产生响应时,会产生set-cookie响应头,将cookie文本发送给客户端,客户端会将cookie文本保存起来,当客户端再次请求服务器时,会产生cookie请求头,将之前服务器发送的cookie信息,再发送给服务器,服务器就可以根据cookie信息跟踪客户端的状态。
cookie的工作原理:
a.服务器通过随着响应发送一个http 的Set-Cookie 头,在客户机中设置一个cookie(多个cookie 要多个头)。
b.客户端自动向服务器端发送一个http 的cookie 头,服务器接收读取。
C.如果是持久化cookie,浏览器将在客户端的磁盘上创建一个cookie 文件,并在里面写入:
TestCookie=something from somewhere;
这一行就是我们用 setcookie('TestCookie','something from somewhere','/'); 的结果。也可以用
header('Set-Cookie: TestCookie=something from somewhere; path=/');的结果。
cookie的分类:
1 存放在客户端浏览器的缓存中,当浏览器不关闭,cookie信息一起存在,浏览器一关闭,cookie消失
2 存放在客户端的文件中,并可以设置cookie过期时间,过期时间之内,即使浏览器关闭,也可以将cookie信息发送给服务器,超过过期时间,cookie消失。
cookie信息是以文本方式(不一定是txt文件,大多是二进制文件)存放在客户端的,所以容易引起一些安全隐患,所以不要把隐秘信息以cookie方式保存。
cookie相关操作(新建+读取+删除)
设置cookie:
a.可以用 setcookie()
-
<span style=
"font-family:SimSun;font-size:12px;">$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及其所有子域名 */
-
</span>
设置多个 cookie 变量:setcookie('var[a]','value'); 用数组来表示变量,但他的下标不用引号。这样就可以用$_COOKIE[‘var’][‘a’]来读取该COOKIE 变量。
b. 使用 header()设置cookie;
header("Set-Cookie: name=$value[;path=$path[;domain=xxx.com[;...]]");
-
<span style=
"font-family:SimSun;font-size:12px;">$value =
'something from somewhere';
-
header(
"Set-Cookie:name=$value");
-
</span>
读取cookie:
<span style="font-family:SimSun;font-size:12px;">print $_COOKIE['TestCookie']; </span>
删除cookie
只需把有效时间设为小于当前时间,和把值设置为空。例如:
<span style="font-family:SimSun;font-size:12px;">setcookie("name", "", time()-1); </span>
//
session的工作流程:
当用户第一次访问站点时,PHP会用session_start()函数为用户创建一个sessionID,这就是针对这个用户的唯一标识,每一个访问的用户都会得到一个自己独有的session ID,这个session ID会存放在响应头里的cookie中,之后发送给客户端。这样客户端就会拥有一个该站点给他的session ID。
当用户第二次访问该站点时,浏览器会带着本地存放的cookie(里面存有上次得到的session ID)随着请求一起发送到服务器,服务端接到请求后会检测是否有session ID,如果有就会找到响应的session文件,把其中的信息读取出来;如果没有就跟第一次一样再创建个新的。
通常站点的退出功能,实际上就是调用一下session_destroy()函数(也有可能更复杂些),把该用户的session文件删除,再把用户的cookie清除。这样客户端和服务端就算没有联系了。
图中的红框部分就是一次完整的HTTP请求,因为HTTP是无状态的,所以一次请求完成后客户端和服务端就不再有任何关系了,谁也不认识谁。但由于一些需要(如保持登录状态等),必须让服务端和客户端保持联系,session ID就成了这种联系的媒介了。

session的工作原理:
最最核心的概念就是:网页间跳转的额外数据,保存在服务器,用一个id标识,浏览器要维持session,需要每次提交都带上这个id.
session 使用过期时间设为0的cookie,并且将一个称为session ID的唯一标识符(一长串字符串),在服务器端同步生成一些 session文件(可以自己定义 session的保存类型),与用户机关联起来。web应用程序存贮与这些 session 相关的数据,并且让数据随着用户在页面之间传递.访问网站的来客会被分配一个唯一的标识符,即所谓的 SESSION ID。它要么存放在客户端的cookie,要么经由 URL 传递.SESSION 允许用户注册任意数目的变量并保留给各个请求使用。当来客访问网站时,PHP会自动(如果session.auto_start被设为1)或在用户请求时(由session_start()明确调用或session_register() 暗中调用)检查请求中是否发送了特定的SESSION ID。如果是,则之前保存的环境就被重建。
session ID的传递有两种方式:
a.通过 cookie 传送 SESSION ID
使用 session_start()调用 session,服务器端在生成session文件的同时,生成变量session name(默认为PHPSESSID)及其对应值为唯一标识用户的session ID(哈希值)(服务端和客户端保存着同样的session ID信息,这就是两者保持联系的钥匙。),并向客户端发送该变量session name(默认为PHPSESSID)及其对应值为唯一标识用户的session ID(哈希值)。服务器端将通过该 cookie 与客户端进行交互。一个被sessionID唯一标识后的用户创建的各种session变量及对应值经php内部序列化后保存在服务器机器上的文本文件中,和客户端的变量名默认情况下为PHPSESSID 的cookie 进行对应交互.即服务器自动发送了http 头:
header('Set-Cookie: session_name()=session_id(); path=/'); 或setcookie(session_name(),session_id());
即:header('Set-Cookie: PHPSESSID=pcnnftkmkm9nua33uot8fmb8a3; path=/'); 或setcookie(PHPSESSID,pcnnftkmkm9nua33uot8fmb8a3);
当从该页跳转到的新页面并调用session_start()后,PHP 将检查与给定ID 相关联的服务器端存贮的session数据,如果没找到,则新建一个数据集。
b.通过URL传送 session ID
只有在用户禁止使用cookie的时候才用这种方法,因为浏览器cookie 已经通用,为安全起见,可不用该方法。
<a href="p.php?<?php print session_name()?>=<?php print session_id() ?>">xxx</a>,也可以通过 POST 来传递session 值。
、、、、、、、、、、、、、、、、、、、、、
如果客户端禁止使用cookie,可以使用如下办法:
a、设置php.ini中的session.use_trans_sid= 1或者编译时打开打开了--enable-trans-sid选项,让PHP自动跨页传递session id。
b、手动通过URL传值、隐藏表单传递session id。
c、用文件、数据库等形式保存session_id,在跨页过程中手动调用。
link:http://apps.hi.baidu.com/share/detail/41643457
session也可以在禁用cookie的情况下使用:
php.ini中session.use_cookies=1,改为0,session会保存在服务器端,而不是客户端的cookie。
可以通过session.save_path来查看服务器的session存放位置
session相关操作(新建+读取+删除)
设置session:
-
<span style=
"font-family:SimSun;font-size:12px;">
// 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将为 (未定义)空
-
*/
-
</span>
读取session
-
<span style=
"font-family:SimSun;font-size:12px;">
//page2.php
-
session_start();
-
print $_SESSION[
'animal'];
// 打印出单个 session
-
var_dump($_SESSION);
// 打印出page1.php传过来的 session值 </span>
删除session
-
<span style=
"font-family:SimSun;font-size:12px;">session_destroy();
// 第一步: 删除服务器端 session文件,这使用
-
setcookie(session_name(),
'',time()
-3600);
// 第 二 步 : 删 除 实 际 的session:
-
$_SESSION =
array();
// 第三步: 删除$_SESSION全局变量数组
-
</span>
------------------------------------------------------------------------------------------------------------------------------
一个简单的示例:
-
<span style=
"font-family:SimSun;font-size:12px;">session_start();
-
if (isset($_SESSION[
'test_sess'])){
-
<span>
</span>$_SESSION[
'test_sess']++;
-
}
else{
-
<span>
</span>$_SESSION[
'test_sess'] =
0;
-
}
-
echo $_SESSION[
'test_sess'];
-
</span>
使用的一个叫做httplook的http包嗅探工具来抓包:
第一次请求服务器:
-
<span style="font-family:SimSun;font-size:12px;">GET /test.php HTTP/1.1
-
Accept: */*
-
Referer: http://localhost/
-
Accept-Language: zh-cn
-
Accept-Encoding: gzip, deflate
-
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322)
-
Host: localhost
-
Connection: Keep-Alive
-
</span>
服务器第一次返回:
-
<span style=
"font-family:SimSun;font-size:12px;">HTTP/
1.1
200 OK
-
Date: Fri,
26 Aug
2005
07:
44:
22 GMT
-
Server: Apache/
2.0
.54 (Win32) SVN/
1.2
.1 PHP/
5.0
.4 DAV/
2
-
X-Powered-
By: PHP/
5.0
.4
-
Set-Cookie: PHPSESSID=bmmc3mfc94ncdr15ujitjogma3; path=/
-
Expires: Thu,
19 Nov
1981
08:
52:
00 GMT
-
Cache-Control: no-store, no-cache, must-revalidate, post-check=
0, pre-check=
0
-
Pragma: no-cache
-
Content-Length:
1
-
Keep-Alive: timeout=
15, max=
99
-
Connection: Keep-Alive
-
Content-Type:
text/html; charset=utf
-8
-
Content-Language:
Off
-
</span>
第二次请求服务器:
-
<span style="font-family:SimSun;font-size:12px;">GET /test.php HTTP/1.1
-
Accept: */*
-
Referer: http://localhost/
-
Accept-Language: zh-cn
-
Accept-Encoding: gzip, deflate
-
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322)
-
Host: localhost
-
Connection: Keep-Alive
-
Cookie: PHPSESSID=bmmc3mfc94ncdr15ujitjogma3
-
</span>
服务器第二次返回:
-
<span style=
"font-family:SimSun;font-size:12px;">HTTP/
1.1
200 OK
-
Date: Fri,
26 Aug
2005
07:
44:
23 GMT
-
Server: Apache/
2.0
.54 (Win32) SVN/
1.2
.1 PHP/
5.0
.4 DAV/
2
-
X-Powered-
By: PHP/
5.0
.4
-
Set-Cookie: PHPSESSID=bmmc3mfc94ncdr15ujitjogma3; path=/
-
Expires: Thu,
19 Nov
1981
08:
52:
00 GMT
-
Cache-Control: no-store, no-cache, must-revalidate, post-check=
0, pre-check=
0
-
Pragma: no-cache
-
Content-Length:
1
-
Keep-Alive: timeout=
15, max=
98
-
Connection: Keep-Alive
-
Content-Type:
text/html; charset=utf
-8
-
Content-Language:
Off
-
</span>
仔细对比这些输出,第二次请求比第一次请求多出来的就是:
Cookie: PHPSESSID=bmmc3mfc94ncdr15ujitjogma3
这个header将会向服务器发送一个cookie信息,告诉服务器我有一个cookie,名字叫PHPSESSID,内容是bmmc3mfc94ncdr15ujitjogma3。
这个cookie是怎么来的呢?看第一次服务器返回的信息里边有:
Set-Cookie: PHPSESSID=bmmc3mfc94ncdr15ujitjogma3; path=/
这是服务器向客户端浏览器写一个cookie,名字是PHPSESSID,值是bmmc3mfc94ncdr15ujitjogma3,这个值实际就是所谓的session_id。
继续看第二次向服务器发出的请求,仍然向服务器发送了PHPSESSID这个cookie
可以得到以下结论:
1、只要使用了session,就会通过cookie的方式向客户端浏览器发送session
2、每次向服务器发出请求的时候,本地浏览器会把cookie附带在请求信息中
session常见问题
一、session是怎么保存的?怎么去查看其内容?
session是以文件的形式保存的。php.ini中有个配置项--session.save_path="";这个里面填写的路径,将会使session文件保存在该路径下。session文件的命名格式是:"sess_[PHPSESSID的值]"。每一个文件,里面保存了一个会话的数据。其实只要使用代码$_SESSION['user_id'] = $value;就会促发php的session机制,结果往对应的session文件中写入一个值。
二、session.save_path路径下这么多的session文件,php是如何确定要调用哪个session文件的?
php是依据,一个名为PHPSESSID的cookie,根据它的值,确定要调用哪个session文件的。去浏览器中,可以看到一个cookie名为PHPSESSID,假如它的值为"sess_adbjsf2q1ass26oootd163sf84",那么,当访问服务器的时候,就会调用session目录下名为"sess_sess_adbjsf2q1ass26oootd163sf84"的文件。其实,PHPSESSID就是一个会话id,以此来确定,哪个是你的会话数据。
以下是在浏览器查看cookie所看到的

cookie的名字PHPSESSID是可以改的,在php.ini中 session.name = PHPSESSID就是设置该cookie的名字。php.ini中有个配置项--session.save_path= "";这个里面填写的路径,将会使session文件保存在该路径下。
三、说说session跟cookie有关联的地方
PHPSESSID这个cookie有绑定关系。其他,不管你设置什么cookie,使用session的时候是不会用到这些值的。也无法获取到。比如同步登陆,设置即使设置了cookie,而你的应用是依据session判断是否为登陆状态的(事实上也必须如此,因为session保存在服务器端,安全性更高,哪个依据cookie认为你已经登陆,那么很惨)。所以,这样的情况就会出现,即使成功设置了cookie。也还是不能同步登陆。
四、经常遇到的现象:为什么删除一个session文件,之后生成一个session文件,新的文件名字还是与原来一样?(但是文件里面的内容会变化)
理解到session文件的命名规则是:“sess_PHPSESSID值“。那么,就很容易明白了。因为,客户端存在cookie:PHPSESSID。客户端发送请求后,会将该cookie发送给服务器(php可以使用$_COOKIE['PHPSESSID']看到其内容),这样的话,还是会根据PHPSESSID生成一个session文件的。
五、如何查看session文件中的session值?
我在开发中发现,如果仅仅依靠session_start()和$_SESSION['user_id']这样的代码,去调试,还不够全面的了解问题所在。比如,我想知道,session_start()到底在完成哪些操作?如果,想动态,实时知道session的值是如何被改写的,打开一个session文件,查看是很了然的。原来,里面就是保存的是一些被序列化后的值。也明白一个知识点,"php圣经"中讲解session的时候,提到session值做被序列化了。下面看到的session内容就是被序列化了。
打开一个session文件,内容如下:
<span style="font-family:SimSun;font-size:12px;">cityID|i:0;cityName|s:3:"all";fanwe_lang|s:5:"zh-cn";fanwe_currency|a:4:{s:2:"id";s:1:"1";s:6:"name_1";s:9:"人民币";s:4:"unit";s:3:"¥";s:5:"radio";s:6:"1.0000";}_fanwe_hash__|s:32:"77c18770c6cb5d89444c407aaa3e8477";</span>
读取规则如下:
1、每一个session的值是以分号";"分开的。比如“cityID|i:0;”就是一个完整的session值结束
2、里面的读取规则:符号“|”前面表示session名称。符号后面是该session的具体信息。包括:数据类型,字符长度,内容。上面第二个就相当于使用如下php代码访问:$_SESSION['cityName'],后面的s表示数据值的长度,3表示字符长度,变量值为all。
3.一个session可以保存一个数组。符号{}表示数组的内容。上面的花括号{}$_SESSION['fanwe_currency']所保存的内容。要想查看id的值,就使用代码:$_SESSION['fanwe_currency']['id']
六、怎么样理解session_start等函数所做的实际操作是什么?
我是这样理解的:session_start,可以看成是创建一个session文件。假如有原来的session文件,或许没有创建。引入一个。往session文件中写值,那是代码“$_SESSION['']=""; 赋值所完成的操作。
session_start()生成一个新的session文件名时。会判断是否存在cookie名为PHPSESSID的值。如果存在,那么就会按照它的值,组合成一个文件名"sess_[phpcookie值]"。所以,在目录下,老是能够看到之前删除过的session文件名。如果将浏览器中对应的cookie(PHPSESSID)删掉。那么就不会生成同样的名字了。如果不存在名为PHPSESSID的cookie。php所做的估计为:先发送一个cookie,然后按照cookie的值生成一个(我可以在浏览器中马上看到一个名为PHPSESSID的cookie)
其实,现在也更加深刻地理解了一个知识:在调用session_start()之前不能有任何输出。有输出就会报错。
session_start()已经封装了发送cookie的操作(发送一个名称为PHPSESSID的cookie到浏览器)。涉及到http的一个原理:头部信息必须在内容之前发送才行。所以,使用echo '内容';
header('Content-type:text/xml; charset=gb2312');//头部信息,不算内容
可以这样认为:session_start()内部已经进行了一次发送头部动作。所以之前不能有任何输出内容。
手册中的英文大致是这样说的:创建一个session,或者恢复当前一个session(基于request请求传递的session id,这里应该值的就是http请求时传递的名为PHPSESSID的cookie)
七、只要是同一个用户的操作。导航程序访问记录和团购程序访问的记录都是保存在同一个session文件中。如果是不同的域呢?假如用户访问cs.test.com和daohang.test.com,两方程序都设置了session。那么session的结果保存在同一个session文件中吗?
是的!因为:服务器是统一管理session文件的存放的。而php引擎是根据phpsessionid的值确定要操作哪个session文件。session文件名的格式是:"sess_[phpcookie值]"。依次寻找对应的session文件(于是在浏览器查看名为PHPSESSIONID的cookie,过期时间是在会话结束后)。所以,只要cs.test.com和daohang.test.com使用的是同一台服务器。就算是不同的域,两方程序都设置了session。那么session的结果保存在同一个session文件中。
这样的话,假如是多台服务器的情况。那么就不得不将session保存在数据库中去。这样实现session共享。
http://www.birdol.com/php/4272.html
http://blog.youkuaiyun.com/wangzhkai/article/details/4187496
http://www.cnblogs.com/wangtao_20/archive/2011/02/16/1955659.html
http://blog.youkuaiyun.com/fangaoxin/article/details/6954925