第16章 Drupal会话(session)(2)会话生命周期

会话生命周期

16-1展示了会话生命周期。从一个浏览器向服务器发送一个请求起,会话开始。在Drupal的引导指令流程的DRUPAL_BOOTSTRAP_SESSION阶段,会话代码开始运行。如果浏览器不能提供以前从站点接收到的cookie的话,PHP的会话管理系统将位浏览器提供一个带有一个新的PHP会话ID的cookie。其中会话ID通常为32位字符串,使用MD5哈希函数处理过。当然,PHP5允许你将配置指令session.hash_function设置为1,使得你可以使用SHA-1哈希来得到40位的字符串作为会话ID。

 

注意:MD5是一个文本字符串的哈希值的算法,也是Drupal选用的默认哈希算法。关于MD5和其它哈希算法的更多信息,参看http://en.wikipedia.org/wiki/Cryptographic_hash_functions

 

Drupal然后检查在表sessions中是否存在以该会话ID为键的记录。如果存在的话,那么函数sess_read()将会话数据取出,并进行一次SQL联合操作,对表sessions中的该记录及表users中的相应记录进行联合,其结果是得到一个包含了两个记录所有字段和值的对象,这就是在后面的Drupal中广泛使用的全局变量$user。那么,通过$user,具体一点就是$user->session也可以访问会话数据。在这里,当前用户的角色也被取出并分配给$user->roles。

 

如果没有一个用户的用户ID和会话中的用户ID相匹配,那会发生什么呢?这个问题具有欺骗性。由于Drupal的表users中默认有一记录其用户ID为0,而且匿名用户在sessions表中其uid指定为0,所以联合总是工作的。

 

当页面发送给浏览器时,最后一步工作就是关闭会话。PHP出发includes/session.inc里面的sess_write()函数,它将$_SESSION(请求期间的)中存放的任何数据都写入到表sessions中。也有例外情况,比如,如果请求者不接受cookie时,在这种情况下,不向表sessions中写入任何数据。这样就可以在网络爬虫抓取页面时,阻止向表sessions中写入数据了,因为表中的数据量的大小直接影响到性能。

 

 

 

16-1 Drupal是如何使用会话来实例化$user对象的

 

会话对话模仿

下面是一些虚拟的例子,展示了通过你的浏览器访问Drupal站点时,都发生了什么,这是从会话角度来看的。

 

初次访问

浏览器:嗨,请给我一个页面。

Drupal:我可以看一下你的cookie么?

浏览器:对不起,我没有;我是第一次访问这里。

Drupal:好吧,给你一个。

 

第二次访问

浏览器:请再给我一个页面。

Drupal:我可以看一下你的cookie么?

浏览器:它在这里。它的会话号码为6tc47s8jd6rls9cugkdrrjm8h5

Drupal:嗯,在我的记录中找不到它。但是还是给你页面。我将会把你的会话ID记下来以备你再次访问。

 

 

拥有帐号的用户

(当一个用户已创建了一个帐号并点击了登录按钮时。)

浏览器:请再给我一个页面。

Drupal:我可以看一下你的cookie么?

浏览器:它在这里。它的会话号码为6tc47s8jd6rls9cugkdrrjm8h5

Drupal:你好,乔!(喃喃而语)你的用户ID为384,你喜欢将你的评论嵌套起来,你的咖啡黑色的。给你一个新的cookie,这样你的会话就不会被盗用。我将记录你的这次访问。玩的愉快。

 

 

常见任务

下面是一些你使用会话或者修改会话设置的常见方式。

 

修改cookie的存活周期

包含会话ID的cookie的存活周期可通过settings.php中的session.cookie_lifetime控制,其默认值为2,000,000秒(大约23天)。如果将该值设为0,当用户关闭浏览器时,cookie将被立即销毁。

 

修改会话名称

当将Drupal部署在多个子域名下面时,就会遇到一个关于会话的常见问题。由于每个子站点使用相同的session.cookie_domain默认值,并且session.name的默认值都为PHPSESSID,用户发现他们在任何给定时间只能登录到一个Drupal子站点。为每一个站点创建一个唯一的会话名称就可以解决这个问题了。将下面设置添加到你的settings.php文件中,其中mysite是你站点的唯一标识符:

ini_set('session.name', 'mysite_PHPSESSID');

其中会话名称只能包含字母数字字符。

 

 

将数据存储在会话中

将数据存储在用户的会话中非常方便,这是因为数据会被会话系统自动存储起来。无论什么时候,你想在用户访问期间为其存储一些数据时(或者多次访问,使用session.cookie_lifetime),使用全局变量$_SESSION:

$_SESSION['favorite_color'] = $favorite_color;

 

接着,在接下来的请求中,使用下面代码取回该值:

$favorite_color = $_SESSION['favorite_color'];

 

如果你知道用户的uid,而且你想为用户存储一些数据,那么有一个更实用的方法,将数据作为一个独立的属性存放在$user对象中,比如$user->foo =$bar,并调用方法user_save()将数据序列化并保存到表users中的data列中。使用会话的好处是,信息是暂时的,并且你不介意它的丢失,或者你想为匿名用户存储一些短期数据,你也可以将它存放在会话中。如果你想将用户的喜好永远的与用户绑定在一起,可将它存储在$user中。

 

警告:$user不能用来为匿名用户存储信息

 

小结

读完本章后,你应该能够:

理解Drupal是如何修改PHP的会话处理的。

理解哪些文件包含会话配置信息。

理解会话生命周期以及在请求期间是如何创建Drupal的$user对象的。

在用户的会话中存储数据和取回数据

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值