精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● PHP>>Session 使用>>用 PHP + MySQL 实现跨域名 Session 功能(一)

主题:用 PHP + MySQL 实现跨域名 Session 功能(一)
发信人: wongkelly()
整理人: dalasthunder(2002-07-25 05:57:28), 站内信件
  常用 ASP 和 PHP 的朋友们对 Session 的用法已不陌生了吧 ^_^ ,不光可以在服务器端保存一些较大量的数据,而且 Client 端看不到保存的任何东东,即方便又保密,但近日我在搞一套系统时要求多台主机共享一套 Session,虽说新版的 PHP 据说有办法实现,但我 E 文不好,相关资料不多,于是我干脆自己写一套,将数据放在同一台数据库 Server 中,虽说加重了其负担,但总算实现了。OK,介绍一下具体方法:
  先要从 Session 的原理说起,当然若您知道那就 Next 吧 ^_^ ,Session 的实现其实靠的是 cookie ,例如当你访问一张 .asp 的页面时, 服务器将会自动生成一个唯一的 Session ID,通过 HTTP Header 一同发至 Client,即在 浏览器 发出访问该页面的请求后接收到的 HTTP 头中含有:
Set-Cookie: ASPSESSIONIDGGQGQKDC=MGENGKFDACFBHGHPIBGMMFHI; path=/
  此 ID 在同一段时间内每一用户访问都不一样,此后只要浏览器不关(这里的关闭是说将打开的窗口全部关掉,即浏览器的进程结束),且使用的浏览器支持 cookie ,浏览器在访问同一站点的其他页面时发出的 HTTP 请求的便会连带着发出
Cookie: ASPSESSIONIDGGQGQKDC=MGENGKFDACFBHGHPIBGMMFHI;
  于是你在其它 asp 页面中写程序读取保存在 Session 中的数据时,服务器就会根据该浏览器所发送的 Session ID 自动的将保存在内存中的 Session 数据取出来使用,于是 Session 功能实现了。
  PHP 中的 Session 原理相同,只不过当调用 session_start(); 函数时才在 HTTP 头加入 Session ID,发送的 cookie 名默认是 PHPSESSID,可在 php.ini 中修改,Session 数据存放在文件中,因此其效率较 asp 差,但倒是很节省内存 ^_^ 。
  好的,讲讲怎么做吧!若希望自己做 Session 功能并不是难事,只不过稍微麻烦一点,但相当灵活,具体思路是:
  在用户访问页面时自动生成一个唯一的 ID,网上有很多事例,例如用
$sessoion_id=md5(uniqid(rand()));
  用这几个函数“联手”生成一个唯一的加密的长 32 位的字符串 ID,安全快速。且黑客门在短时间内极难破解。
  然后将这个 ID 用 setcookie() 函数加入 HTTP 头发送出去,当然若你习惯用 header() 函数 效果一样。同时要在服务器端保留该 ID 以便在下一次用户访问时可取出 Session 数据,例如连接数据库将 ID 插入一 table,将 Session 数据一并存进去。于是当你使用多台主机时,只要{
  一、多台主机使用的是同一台数据库服务器;
  二、用 setcookie() 时域相同;
}
//(↑就是说使用 setcookie() 函数时,参数 domain 相同,cookie 规定:在设置 cookie 时可指定该 cookie 的域名,就是说设定在浏览器访问哪些域名一同在 HTTP 请求中加入这个 cookie,例如设置该 cookie 的域为 test.com,那么浏览器在访问 a.test.com,b.test.com、即 *.test.com 都会发送此 cookie)
  其他要注意的就是 Session 的 Timeout 了,要在用户不再浏览本站的页面后超过一定时间将它所用过的 Session 数据删除,在 ASP 中的 Session 超时估计是靠的一个低优先级的线程不断循环检测,一旦某 Session 不再活动超过 20 分钟就执行用户的 Session_OnEnd 过程(即激发该事件),并释放其所占的内存。而若在 PHP  中实现恐怕只有靠下一个用户连接时再检测前面的 Session 是否已过期然后处理,所以要注意的是假若希望写一个类似 Session_OnEnd 的函数,则不能在其中以当前时间确定用户离开时间,因为假若在相当长时间内没人浏览站点,那么有可能这个 Session 可能要到下一次有人浏览时才释放,并执行 OnEnd 处理函数,所以 OnEnd 处理函数执行时有可能已到了几天后 ^_^ 。


[关闭][返回]