PHP session和cookie

<?php
//===========================================================cookie
//cookie是在服务器端被创建并写回到客户端浏览器,浏览器接到响应头中关于写cookie的指令则在本地临时文件夹中创建了一个cookie文件,其中保存了cookie内容,cookie内容的存储是键值对的方式,键和值都只能是字符串
//cookie标题头必须在发送其他标题头之前发送,否则就无效(这是cookie的限制,而不是PHP的限制)。

//服务器在发送 cookie 时,cookie 的值会自动进行 URL 编码,在取回时进行自动解码。如不想 URL 编码,请使用 setrawcookie() 取代 setcookie(),setrawcookie() 与 setcookie() 几乎完全相同,不同的是不会在发往客户机时,对 cookie 值进行自动 URL 编码。
//cooke有四个标识符(用来判断是否同一个cookie):cookie的name,domain,path,secure标记。要想在将来改变这个cookie的值,需要发送另一个具有相同cookie name,domain,path的Set-Cookie消息头,这将以一个新的值来覆盖原来cookie的值。然而,如果仅仅只是改变这些选项的某一个也会创建一个完全不同的cookie,如只是更改了domain值,(secure应为网站整体统一配置,一般不单独修改)

//当一个cookie被设置好或已存在,并且可选条件允许的话,该cookie的值会在接下来的每个请求中被发送至服务器。cookie的值被存储在名为Cookie的HTTP消息头中,并且只包含了cookie的值,其它的选项全部被去除。例如:Cookie : value
//Set-Cookie指定的属性选项只是应用于浏览器端,一旦属性选项被设置后便不会被服务器重新取回。浏览器中传递的cookie值与Set-Cookie中指定的值是完全一样的字符串;对于这些值不会有更近一步的解析或转码操作。如果在指定的请求中有多个cookies,那么它们会被分号和空格分开,例如:Cookie:value1 ; value2 ; name1=value1




//通常设置cookie格式如下,各参数顺序随意,紧跟cookie值后面的每个选项都以分号和空格分割,并且每个选项都指定cookie什么条件下应该被发送到服务器。
//name即为此cookie的键值名称。value为对应值
//expires,值是当前时间戳+有效时长秒数,其指定了cookie何时不会再被发送到服务器端的,因此过期后cookie可能会被浏览器删掉。在没有expires选项时,cookie的寿命仅限于单一的会话中。浏览器的关闭意味这一次会话的结束,所以会话cookie只存在于浏览器保持打开的状态之下。这就是为什么当登录到一个web应用时经常看到一个checkbox,询问是否选择存储登录信息:如果选择是的话,那么一个expires选项会被附加到登录的cookie中。如果expires选项设置了一个过去的时间点,那么这个cookie会被立即删除
//path,与domain选项相同的是,path指明了浏览器在发cookie消息之前必须在请求url中存在一个指定url路径。这个比较是通过将path属性值与请求的URL从头开始逐字符串比较完成的。如果字符匹配,则发送cookie消息头,例如:"path=/blog"。通常该值设置为"path=/",即所有路径包含 "/" 的请求浏览器都会发送该cookie(前提同时满足domain值)
//domain,指示浏览器把本地的cookie将要发送到哪些以domain值结尾的域名中,注意domain值的第一个字符必须是".",列如 "domain=.google.com" 则所有以"google.com"结尾的域名都可以访问该cookie。默认情况下,domain会被设置为创建该cookie的页面所在的域名。想象诸如Yahoo!这样的大型网站都会有许多以name.yahoo.com(例如:my.yahoo.com,finance.yahoo.com,等等)为格式的站点。单独的一个cookie可以简单的通过将其domain选项设置为yahoo.com而发送到所有这些站点中。浏览器会对domain的值与请求所要发送至的域名,做一个尾部比较(即从字符串的尾部开始比较),并且在匹配后发送cookie消息
//secure,不像其它选项,该选项只是一个标记并且没有其它的值。一个secure cookie只有当请求是通过SSL和HTTPS创建时,才会发送到服务器端。
//httpOnly,禁止浏览器端js通过document.cookie属性访问cookie,以下有详解
header("Set-Cookie:name=value [ ;expires=date][ ;path=path][ ;domain=domain][ ;secure][ ;httpOnly]");


//cookie会被浏览器自动删除,通常存在以下几种原因:
/*
会话cooke(Session cookie)在会话结束时(浏览器关闭)会被删除
持久化cookie(Persistent cookie)在到达失效日期时会被删除
如果浏览器中的cookie限制到达,那么cookies会被删除以为新建cookies创建空间。
*/



//Cookie限制条件
/*
在cookies上存在了诸多限制条件,来阻止cookie滥用并保护浏览器和服务器免受一些负面影响。有两种cookies的限制条件:cookies的属性和cookies的总大小。原始的规范中限定每个域名下不超过20个cookies,早期的浏览器都遵循该规范,并且在IE7中有个更近一步的提升。在微软的一次更新中,他们在IE7中增加cookies的限制到50个,与此同时Opera限定cookies个数为30.Safari和Chrome对与每个域名下的cookies个数没有限制。
发向服务器的所有cookies的最大数量(空间)仍旧维持原始规范中所指出的:4KB。所有超出该限制的cookies都会被截掉并且不会发送至服务器。
*/



//HttpOnly cookies
/*
微软的IE6 SP1在cookies中引入了一个新的选项:HTTP-only cookies.HTTP-Only背后的意思是告之浏览器该cookie绝不应该通过Javascript的document.cookie属性访问。设计该特征意在提供一个安全措施来帮助阻止通过Javascript发起的跨站脚本攻击(XSS)窃取cookie的行为(我会在另一篇博客中讨论安全问题,本篇如此已足够)。今天Firefox2.0.0.5+,Opera9.5+,Chrome都支持HTTP-Only cookies。3.2版本的Safari仍不支持。
要创建一个HTTP-Only cookie,只要向cookie中添加一个HttpOnly标记即可,例如:
header("Set-Cookie:name=value; HttpOnly");
也可以在php.ini中设置
session.cookie_httponly = 1
或者在PHP代码中输入 
ini_set("session.cookie_httponly", 1);
不能通过JavaScript设置HTTP-only cookies,因为不能再通过JavaScript读取这些cookies,这是情理之中的事情。
*/


$cookieValue = 'cookieValue';

//以下两种方法均可以创建cookie
//1,
header("Set-Cookie:cookieName=$cookieValue;expire=".(time()+3600).";path=/;domain=.google.com;secure;httpOnly");
//2,
setcookie("cookieName", $cookieValue, time()+3600,"/",".google.com",true,true);



echo $_COOKIE["cookieName"];

//清除cookie
setcookie("cookieName", '', time()+3600,"/",".google.com",true,true);
//
setcookie("cookieName", $cookieValue, time()-1,"/",".google.com",true,true);


//$HTTP_COOKIE_VARS["cookieName"] 与 $_COOKIE["cookieName"] 均可获取 cookieName 的 cookie 的值。


//以下为安全设置,设置 cookie 保存的 session_id 只在 https 中传递,最好在 session_start(); 之后执行
setcookie(session_name(), session_id(), 0, "/",'.google.com',true);
session_set_cookie_params(0,'/','.google.com',true,true);









//===========================================================session
/*
浏览器访问页面 a.php 时候,服务器产生一个 session 文件,将其存放在服务器,同时将 session_id 发送给浏览器,浏览器将其保存到 cookie ,浏览器在访问 b.php 时候,从 cookie 中获取 session_id 发送到服务器,服务器根据 session_id 获取相应 session 内容

如果浏览器禁用cookie,怎么使用session呢?这时需要使用url重写的方式
url重写分为自动和手动。
自动模式:
自动重写url就是配置 php.ini ,开启透明的SID,其他程序不变,自动重写 url 不安全,不建议使用。
开启透明SID,需要修改的php.ini是:
session.use_trans_sid = 1     //由默认 0 改为 1
session.use_only_cookies = 0  //由默认 1 改为 0
session.use_cookies = 0       //由默认 1 改为 0,该参数的值不影响上述机制的进行。这个可改可不改


手动模式:
index.php 页代码
//=========================== index.php 页开始===========================
session_start ();
$_SESSION ['name'] = "testname";
$_SESSION ['age']  = 100;

echo 'session save succes! click <a href="index2.php?' . SID . '">here</a> to see SID<br/>';
//=========================== index.php 页结束===========================

index2.php 页代码
//=========================== index2.php 页开始===========================
if ($_GET ["PHPSESSID"]) {
    //将从url获取的session_id,赋给程序,让程序使用指定session_id的会话
    session_id ( $_GET ["PHPSESSID"] );
}
session_start ();
echo session_id () . '<br/>';
echo $_SESSION ['name'];
//=========================== index2.php 页结束===========================

在浏览器上输入地址
http://localhost/test/index.php
点击页面链接后会跳转到地址
http://localhost/test/index2.php?
并且显示内容
m1n82u8sk2lkqb5rpi5purrfn5
testname
这里 m1n82u8sk2lkqb5rpi5purrfn5 即为本次会话的 session_id
自动模式,会将url后面自动添加PHPSESSID参数,所以在index.php中去掉SID即可,index2.php不变






*/
//凡是需要使用 session 的php文件起始输出内容前都要执行此方法。除非用框架全局只需要执行一个index.php文件,那么在index.php文件中写一次该方法即可
session_start();


//输出当前session会话id,每个会话id唯一
echo session_id () . '<br/>';
//输出php.ini设置的session名,这里是 PHPSESSID,也是 cookie 里的键值,对应值就是session_id
echo session_name(). '<br/>';
//输出cookie里存的 session_id,浏览器的cookie只保存session的id不保存session里的值
echo $_COOKIE[session_name()] . '<br/>';




//设置session
$_SESSION['sessionName'] = "sessionValue";

//使用session
echo $_SESSION['sessionName'];

//销毁session

//退出登录前执行
setcookie(session_name(), session_id(), time() -1);
//这会删除所有的$_SESSION数据,刷新后,有COOKIE传过来,但是没有数据。
$_SESSION = array();
//这个作用更彻底,删除$_SESSION 删除session文件,和session_id
session_destroy();



/*
session.gc_maxlifetime = 1440    //session数据默认存在时间是1440s(24分钟),当session文件在1440s后没被访问的话,则该session被视为“垃圾文件”,并且等待 gc(垃圾回收) 进程的调用时候被清理掉
;session.save_path = "/tmp"      //默认未启用,改变sesion文件存放路径,一般为了保证服务器的安全,session.save_path 值最好设置为外网无法访问的目录,另外如果是在 linux 服务器下进行 session 配置,请务必同时配置此目录为可读写权限,否则在执行 session 操作时会报错
session.auto_start = 0           //session使用前,要先进行初始化 session_start(); 如果嫌麻烦,可以将 session.auto_start 值设为1自动初始化,(此设置不推荐,最好默认0)


session.cookie_lifetime = 0      //默认为0,传递 session_id 的 cookie 有效期(秒),0表示仅在浏览器打开期间有效。以秒数指定了发送到浏览器的cookie的生命周期,值为0表示“直到关闭浏览器”。
session.name = PHPSESSID         //这里设置的 PHPSESSID 作为 cookie 的键值来获取 对应的 session_id 值。如 echo $_COOKIE["PHPSESSID"]; 就会输出 session_id 值 m1n82u8sk2lkqb5rpi5purrfn5(本次会话 session_id 值)


session.gc_probability = 1       //查看如下 session.gc_divisor
session.gc_divisor = 100         //定义在每次初始化会话时,启动垃圾回收进程的概率。计算公式如下:session.gc_probability/session.gc_divisor,这里是 1/100,表示有 1% 的概率启动启动垃圾回收程序,对会话页面访问越频繁,概率就应当越小。建议值为 1/1000~5000。


session.use_trans_sid = 0        //开启后,默认为每个url后添加了session_name=session_id
session.use_only_cookies = 1     //是否只使用cookie来保存传递 session_id值。当 session.use_trans_sid 为1有效时,session.use_only_cookies 一定要设置为 0 无效。如果该参数为1时,则即使 session.use_trans_sid = 1 也无效,此时禁止用户通过 url 来传递 session_id,客户端如果禁用 cookie 将使 session 无法工作。
session.use_cookies = 1          //设置客户端是否使用cookie来保存session值
*/

//如果是多服务器共用session则最好将session以session_id为键值保存到数据库或独立共享的服务器中

 

posted @ 2012-10-07 21:17  风吹屁股凉冰冰  阅读(556)  评论(0编辑  收藏  举报