PHP5之session完全篇

系统 2318 0
1. 什么是 session?
Session 的中文译名叫做 会话 ,其本来的含义是指有始有终的一系列动作 / 消息,比如打电话时从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一个 session 。目前社会上对 session 的理解非常混乱:有时候我们可以看到这样的话 在一个浏览器会话期间, ...” ,这里的会话是指从一个浏览器窗口打开到关闭这个期间; 也可以看到 用户(客户端)在一次会话期间 这样一句话,它可能指用户的一系列动作(一般情况下是同某个具体目的相关的一系列动作,比如从登录到选购商品到结账登出这样一个网上购物的过程;然而有时候也可能仅仅是指一次连接;其中的差别只能靠上下文来推断了。
然而当 session 一词与网络协议相关联时,它又往往隐含了 面向连接 / 保持状态 这样两个含义, 面向连接 指的是在通信双方在通信之前要先建立一个通信的渠道,比如打电话,直到对方接了电话通信才能开始。 保持状态 则是指通信的一方能够把一系列的消息关联起来,使得消息之间可以互相依赖,比如一个服务员能够认出再次光临的老顾客并且记得上次这个顾客还欠店里一块钱。这一类的例子有 一个 TCP session” 或者 一个 POP3 session”
鉴于这种混乱已不可改变,要为 session 下个定义就很难有统一的标准。而在阅读 session 相关资料时,我们也只有靠上下文来推断理解了。不过我们可以这样理解:例如我们打电话,从拨通的那一刻起到挂断电话期间,因为电话一直保持着接通的状态, 所以把这种接通的状态叫做 session 。它是访客与整个网站交互过程中一直存在的公有变量,在客户端不支持 COOKIE 的时候,为了保证数据正确、安全,就采用 SESSION 变量。访问网站的来客会被分配一个唯一的标识符,即所谓的会话 ID 。它要么存放在客户端的 cookie ,要么经由 URL 传递。
SESSION
的发明填补了 HTTP 协议的局限: HTTP 协议被认为是无状态协议,无法得知用户的浏览状态,当它在服务端完成响应之后,服务器就失去了与该浏览器的联系。这与 HTTP 协议本来的目的是相符的,客户端只需要简单的向服务器请求下载某些文件,无论是客户端还是服务器都没有必要纪录彼此过去的行为,每一次请求之间都是独立的,好比一个顾客和一个自动售货机或者一个普通的(非会员制)大卖场之间的关系一样。
因此通过 SESSION(cookie 是另外一种解决办法 ) 记录用户的有关信息,以供用户再次以此身份对 web 服务器提起请求时作确认。会话的发明使得一个用户在多个页面间切换时能够保存他的信息。网站编程人员都有这样的体会,每一页中的变量是不能在下一页中使用的 ( 虽然 form url 也可以实现,但这都是非常不理想的办法 ) ,而 SESSION 中注册的变量就可以作为全局变量使用了。
那么 SESSION 到底有什么用处呢?网上购物时大家都用过购物车,你可以随时把你选购的商品加入到购物车中,最后再去收银台结帐。在整个过程中购物车一直扮演着临时存贮被选商品的角色,用它追踪用户在网站上的活动情况,这就是 SESSION 的作用,它可以用于用户身份认证,程序状态记录,页面之间参数传递等。
SESSION
的实现中采用 COOKIE 技术, SESSION 会在客户端保存一个包含 session_id(SESSION 编号 ) COOKIE ;在服务器端保存其他 session 变量,比如 session_name 等等。当用户请求服务器时也把 session_id 一起发送到服务器,通过 session_id 提取所保存在服务器端的变量,就能识别用户是谁了。同时也不难理解为什么 SESSION 有时会失效了。
当客户端禁用 COOKIE ( 点击 IE 中的 工具 ”—“Internet 选项 ,在弹出的对话框里点击 安全 ”—“ 自定义级别 项,将 允许每个对话 COOKIE” 设为禁用 ) session_id 将无法传递,此时 SESSION 失效。不过 PHP5 linux/unix 平台可以自动检查 cookie 状态,如果客户端设置了禁用,则系统自动把 session_id 附加到 url 上传递。 windows 主机则无此功能。

2. Session 常见函数及用法?
Session_start() 开始一个会话或者返回已经存在的会话。
说明:这个函数没有参数,且返回值均为 true 。如果你使用基于 cookie session(cookie-based sessions), 那么在使用 Session_start() 之前浏览器不能有任何输出,否则会发生以下错误:
Warning: Cannot send session cache limiter - headers already sent (output started at /usr/local/apache/htdocs/cga/member/1.php:2)…………
你可以在 php.ini 里启动 session.auto_start=1 ,这样就无需每次使用 session 之前都要调用 session_start() 。但启用该选项也有一些限制,如果确实启用了 session.auto_start ,则不能将对象放入会话中,因为类定义必须在启动会话之前加载以在会话中重建对象。
请求结束后所有注册的变量都会被序列化。已注册但未定义的变量被标记为未定义。在之后的访问中这些变量也未被会话模块定义,除非用户以后定义它们。
警告:有些类型的数据不能被序列化因此也就不能保存在会话中。包括 resource 变量或者有循环引用的对象(即某对象将一个指向自己的引用传递给另一个对象)。
注册 SESSION 变量:
PHP5 使用 $_SESSION[‘xxx’]=xxx 注册 SESSION 全局变量。和 GET POST COOKIE 的使用方法相似。
注意: session_register() session_unregister session_is_registered php5 下不再使用,除非在 php.ini 里把 register_globle 设为 on ,不过出于安全考虑,强烈建议关闭 register_globle HTTP_SESSION_VARS 也不提倡使用了,官方建议用 $_SESSION 代替之。例如:
Page1.php
<? php
Session_start (); // 使用SESSION前必须调用该函数。
$_SESSION [‘name’] = ”我是Sunglow ! ”; // 注册一个SESSION变量
$_SESSION [‘passwd’] = ”mynameisSunglow”;
$_SESSION [‘ time ’] = time ();
echo ' <br/><ahref="page2.php">通过COOKIE传递SESSION</a> ' ; // 如果客户端支持cookie,可通过该链接传递session到下一页。
echo ' <br/><ahref="page2.php? ' . SID . ' ">通过URL传递SESSION</a> ' ; // 客户端不支持cookie时,使用该办法传递session.
?>

Page2.php
<? php
session_start ();
echo $_SESSION [ ' name ' ]; //
echo $_SESSION [ ' passwd ' ]; //
echo date ( ' YmdH:i:s ' , $_SESSION [ ' time ' ]);
echo ' <br/><ahref="page1.php">返回山一页</a> ' ;
?>


有两种方法传递一个会话 ID
cookie
URL
参数
会话模块支持这两种方法。 cookie 更优化,但由于不总是可用,也提供替代的方法。第二种方法直接将会话 ID 嵌入到 URL 中间去。
PHP
可以透明地转换连接。除非是使用 PHP 4.2 或更新版本,需要手工在编译 PHP 时激活。在 Unix 下,用 --enable-trans-sid 配置选项。如果此配置选项和运行时选项 session.use_trans_sid 都被激活 ( 修改 php.ini) ,相对 URI 将被自动修改为包含会话 ID
session_id
session_id() 用于设定或取得当前 session_id php5 中既可以使用 session_id() ,也可以通过附加在 url 上的 SID 取得当前会话的 session_id session_name
如果 session_id() 有具体指定值的话,将取代当前的 session_id 值。使用该函数前必须启动会话: session_start();
当我们使用 session cookies 时,如果指定了一个 session_id() 值,每次启动 session_start() 都会往客户端发送一个 cookie 值。不论当前 session_id 是否与指定值相等。
session_id()
如果没有指定值,则返回当前 session_id(); 当前会话没有启动的话,则返回空字符串。
检查 session 是否存在?
在以往的 php 版本中通常使用 session_is_register() 检查 session 是否存在,如果您使用 $_SESSION[‘XXX’]=XXX 来注册会话变量,则 session_is_register() 函数不再起作用。你可以使用
isset($_SESSION[‘xxx’])
来替代。
更改 session_id session_regenerate_id() 更改成功则返回 true ,失败则返回 false
使用该函数可以为当前 session 更改 session_id ,但不改变当前 session 的其他信息。例如:
<? php
session_start ();
$old_sessionid = session_id ();
session_regenerate_id ();
$new_sessionid = session_id ();
echo " 原始SessionID:$old_sessionid<br/> " ;
echo " 新的SessionID:$new_sessionid<br/> " ;
echo " <pre> " ;
print_r ( $_SESSION );
echo " </pre> " ;
?>


session_name() 返回当前 session name 或改变当前 session name 。如果要改变当前 session name ,必须在 session_start() 之前调用该函数。注意: session_name 不能只由数字组成,它至少包含一个字母。否则会在每时每刻都生成一个新的 session id.
session
改名示例:
<? php
$previous_name = session_name ( " WebsiteID " );
echo " 新的session名为:$previous_name<br/> " ;
?>


如何删除 session
1 unset ($_SESSION['xxx']) 删除单个 session unset($_SESSION['xxx']) 用来 unregister 一个已注册的 session 变量。其作用和 session_unregister() 相同。 session_unregister() PHP5 中不再使用,可将之打入冷宫。
unset($_SESSION)
此函数千万不可使用,它会将全局变量 $_SESSION 销毁,而且还没有可行的办法将其恢复。用户也不再可以注册 $_SESSION 变量。
2 $_SESSION=array() 删除多个 session
3
session_destroy() 结束当前的会话,并清空会话中的所有资源。。该函数不会 unset( 释放 ) 和当前 session 相关的全局变量 (globalvariables), 也不会删除客户端的 session cookie.PHP 默认的 session 是基于 cookie 的,如果要删除 cookie 的话,必须借助 setcookie() 函数。
返回值:布尔值。
功能说明:这个函数结束当前的 session ,此函数没有参数,且返回值均为 true

session_unset()
如果使用了 $_SESSION ,则该函数不再起作用。由于 PHP5 必定要使用 $_SESSION ,所以此函数可以打入冷宫了。

下面是 PHP 官方关于删除 session 的案例:
<? php
// 初始化session.
session_start ();
/* **删除所有的session变量..也可用unset($_SESSION[xxx])逐个删除。*** */
$_SESSION = array ();
/* **删除sessinid.由于session默认是基于cookie的,所以使用setcookie删除包含sessionid的cookie.** */
if ( isset ( $_COOKIE [ session_name ()])){
setcookie ( session_name () , '' , time () - 42000 , ' / ' );
}
// 最后彻底销毁session.
session_destroy ();
?>

由此我们可以得出删除 Session 的步骤:
session_start()
$_SESSION=array() /unset($_SESSION['xxx'])
session_destroy()
● SESSION 安全 :
会话模块不能保证存放在会话中的信息只能被创建该会话的用户看到。根据其存放的数据,还需要采取更多措施来主动保护会话的完整性。
评估会话中携带的数据并实施附加保护措施通常要付出代价,降低用户的方便程度。例如,如果要保护用户免于受简单的社交策略侵害(注:指在 URL 中显示的会话 ID 会被别人在电脑屏幕上看到,或被别的网站通过 HTTP Referer 得到等),则应该启用 session.use_only_cookies 。此情形下,客户端必须无条件启用 cookie ,否则会话就不工作。
有几种途径会将现有的会话 ID 泄露给第三方。泄露出的会话 ID 使第三方能够访问所有与指定 ID 相关联的资源。第一, URL 携带会话 ID 。如果连接到外部站点,包含有会话 ID URL 可能会被存在外部站点的 Referer 日志中。第二,较主动的攻击者可能会侦听网段的数据包。如果未加密,会话 ID 会以明文方式在网络中流过。对此的解决方式是在服务器上实施 SSL 并强制用户使用。
默认情况下,所有与特定会话相关的数据都被存储在由 INI 选项 session.save_path 指 定的目录下的一个文件中。对每个会话会建立一个文件(不论是否有数据与该会话相关)。这是由于每打开一个会话即建立一个文件,不论是否有数据写入到该文件 中。注意由于和文件系统协同工作的限制,此行为有个副作用,有可能造成用户定制的会话处理器(例如用数据库)丢失了未存储数据的会话。
上面介绍函数下文将会用到,但还有一些有关 session 的函数也介绍一下:
session_encode
函数功能: sesssion 信息编码
函数原型: string session_encode(void);
返回值:字符串
功能说明:返回的字符串中包含全局变量中各变量的名称与值,形式如: a|s:12:"it is a test \";c|s:4:"lala"; a 是变量名 s:12 代表变量 a 的值 "it is a test 的长度是 12 变量间用分号 ”;” 分隔。
session_decode
函数功能: sesssion 信息解码
函数原型: boolean session_decode (string data)
返回值:布尔值
功能说明:这个函数可将 session 信息解码,成功则返回逻辑值 true
PHP5
不再使用 session_id ,而是把它变成一个常量 SID ,并保存在 cookie 中。如果客户端禁用了 cookie php 会自动通过 url 自动传动传递 SID ,其条件是设置 php.ini 中的 session.use_trans_sid = 1 。此时即使客户端即使禁用了 cookie 也没关系了。
strip_tags() 来输出 SID 以避免 XSS 相关的攻击。
Session 跨页传递问题:
分享到:
评论

PHP5之session完全篇


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论