|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
我假设你目前已经可以完成一个静态页面了,当然,做的好看难看是另外一说,皮皮我的第一个网页也没好看到哪去,但是“孩子”再丑,咱们做“爹妈”的也不能嫌弃不是?这毕竟是咱的成果。session|办事器|数据 1、成绩发源
稍大一些的网站,凡是城市有好几个办事器,每一个办事器运转着分歧功效的模块,利用分歧的二级域名,而一个全体性强的网站,用户体系是一致的,即一套用户名、暗码在全部网站的各个模块中都是可以登录利用的。各个办事器同享用户数据是对照轻易完成的,只需求在后端放个数据库办事器,各个办事器经由过程一致接口对用户数据停止会见便可。但还存在一个成绩,就是用户在这个办事器登录以后,进入另外一个办事器的其余模块时,依然需求从头登录,这就是一次登录,全体通行的成绩,映照到手艺上,其实就是各个办事器之间若何完成同享 SESSION 数据的成绩。
2、PHP SESSION 的任务道理
在处理成绩之前,先来懂得一下 PHP SESSION 的任务道理。在客户端(如阅读器)登录网站时,被会见的 PHP 页面可使用 session_start() 翻开 SESSION,如许就会发生客户真个独一标识 SESSION ID(此 ID 可经由过程函数 session_id() 获得/设置)。SESSION ID 可以经由过程两种体例保存在客户端,使得恳求分歧的页面时,PHP 法式可以获知客户真个 SESSION ID;一种是将 SESSION ID 主动到场到 GET 的 URL 中,或 POST 的表单中,默许情形下,变量名为 PHPSESSID;另外一种是经由过程 COOKIE,将 SESSION ID 保留在 COOKIE 中,默许情形下,这个 COOKIE 的名字为 PHPSESSID。这里咱们次要以 COOKIE 体例停止申明,由于使用对照普遍。
那末 SESSION 的数据保留在哪里呢?固然是在办事器端,但不是保留在内存中,而是保留在文件或数据库中。默许情形下,php.ini 中设置的 SESSION 保留体例是 files(session.save_handler = files),即便用读写文件的体例保留 SESSION 数据,而 SESSION 文件保留的目次由 session.save_path 指定,文件名以 sess_ 为前缀,后跟 SESSION ID,如:sess_c72665af28a8b14c0fe11afe3b59b51b。文件中的数据便是序列化以后的 SESSION 数据了。假如会见量大,能够发生的 SESSION 文件会对照多,这时候可以设置分级目次停止 SESSION 文件的保留,效力会进步良多,设置办法为:session.save_path="N;/save_path",N 为分级的级数,save_path 为入手下手目次。当写入 SESSION 数据的时分,PHP 会获得到客户真个 SESSION_ID,然后依据这个 SESSION ID 到指定的 SESSION 文件保留目次中找到响应的 SESSION 文件,不存在则创立之,最初将数据序列化以后写入文件。读取 SESSION 数据是也是相似的操作流程,对读出来的数据需求停止解序列化,生成响应的 SESSION 变量。
3、多办事器同享 SESSION 的次要妨碍及处理举措
经由过程懂得 SESSION 的任务道理,咱们可以发明,在默许情形下,各个办事器会各自分离对同
一个客户端发生 SESSION ID,如关于统一个用户阅读器,A 办事器发生的 SESSION ID 是 30de1e9de3192ba6ce2992d27a1b6a0a,而 B 办事器生成的则是 c72665af28a8b14c0fe11afe3b59b51b。别的,PHP 的 SESSION 数据都是分离保留在
本办事器的文件体系中。以下图所示:
肯定了成绩地点以后,就能够着手停止处理了。想要同享 SESSION 数据,那就必需完成两个方针:一个是各个办事器对统一个客户端发生的 SESSION ID 必需不异,而且可经由过程统一个 COOKIE 停止传递,也就是说各个办事器必需可以读取统一个名为 PHPSESSID 的 COOKIE;
另外一个是 SESSION 数据的存储体例/地位必需包管各个办事器都可以会见到。复杂地说就是多办事器同享客户真个 SESSION ID,同时还必需同享办事器真个 SESSION 数据。
第一个方针的完成其实很复杂,只需求对 COOKIE 的域(domain)停止特别地设置便可,
默许情形下,COOKIE 的域是以后办事器的域名/IP 地址,而域分歧的话,各个办事器所设
置的 COOKIE 是不克不及互相会见的,如
4、代码完成
起首创立数据表,MySQL 的 SQL 语句以下:
CREATE TABLE `sess` (
`sesskey` varchar(32) NOT NULL default "",
`expiry` bigint(20) NOT NULL default "0",
`data` longtext NOT NULL,
PRIMARY KEY (`sesskey`),
KEY `expiry` (`expiry`)
) TYPE=MyISAM
sesskey 为 SESSION ID,expiry 为 SESSION 过时工夫,data 用于保留 SESSION 数据。
默许情形下 SESSION 数据是以文件体例保留,想要利用数据库体例保留,就必需从头界说 SESSION 各个操作的处置函数。PHP 供应了session_set_save_handle() 函数,可以用此函数自界说 SESSION 的处置进程,固然起首要先将 session.save_handler 改成 user,可在 PHP 中停止设置:
session_module_name("user");
接上去侧重讲一下 session_set_save_handle() 函数,
此函数有六个参数:
session_set_save_handler ( string open, string close, string read, string write, string destroy, string gc )各个参数为各项操作的函数名,这些操作顺次是:翻开、封闭、读取、写入、烧毁、渣滓收受接管。PHP 手册中有具体的例子,
在这里咱们利用 OO 的体例来完成这些操作,具体代码以下:
代码:[size=+0]<?php
define("MY_SESS_TIME", 3600);
//SESSION 保存时长
//类界说
class My_Sess
{
function init()
{
$domain = ".infor96.com";
//不利用 GET/POST 变量体例
ini_set("session.use_trans_sid",0);
//设置渣滓收受接管最大保存工夫
ini_set("session.gc_maxlifetime",MY_SESS_TIME);
//利用 COOKIE 保留 SESSION ID 的体例
ini_set("session.use_cookies",1);
ini_set("session.cookie_path","/");
//多主机同享保留 SESSION ID 的 COOKIE
ini_set("session.cookie_domain", $domain);
//将 session.save_handler 设置为 user,
//而不是默许的 files
session_module_name("user");
//界说 SESSION 各项操作所对应的办法名:
session_set_save_handler(
array("My_Sess", "open"),
//对应于静态办法 My_Sess::open(),下同。
array("My_Sess", "close"),
array("My_Sess", "read"),
array("My_Sess", "write"),
array("My_Sess", "destroy"),
array("My_Sess", "gc")
);
} //end function
function open($save_path, $session_name) {
return true;
} //end function
function close() {
global $MY_SESS_CONN;
if ($MY_SESS_CONN) {
//封闭数据库毗连
$MY_SESS_CONN->Close();
}
return true;
} //end function
function read($sesskey) {
global $MY_SESS_CONN;
$sql = "SELECT data FROM sess WHERE sesskey=".$MY_SESS_CONN->qstr($sesskey)." AND expiry>=".time();
$rs =& $MY_SESS_CONN->Execute($sql);
if ($rs) {
if ($rs->EOF) {
return "";
} else {
//读取到对应于 SESSION ID 的 SESSION 数据
$v = $rs->fields[0];
$rs->Close();
return $v;
} //end if
} //end if
return "";
} //end function
function write($sesskey, $data) {
global $MY_SESS_CONN;
$qkey = $MY_SESS_CONN->qstr($sesskey);
$expiry = time() + My_SESS_TIME;
//设置过时工夫
//写入 SESSION
$arr = array(
"sesskey" => $qkey,
"expiry" => $expiry,
"data" => $data);
$MY_SESS_CONN->WordStr("sess", $arr, "sesskey", $autoQuote = true);
return true;
} //end function
function destroy($sesskey) {
global $MY_SESS_CONN;
$sql = "DELETE FROM sess WHERE sesskey=".$MY_SESS_CONN->qstr($sesskey);
$rs =& $MY_SESS_CONN->Execute($sql);
return true;
} //end function
function gc($maxlifetime = null) {
global $MY_SESS_CONN;
$sql = "DELETE FROM sess WHERE expiry<".time();
$MY_SESS_CONN->Execute($sql);
//因为常常性的对表 sess 做删除操作,轻易发生碎片,
//所以在渣滓收受接管中对该表停止优化操作。
$sql = "OPTIMIZE TABLE sess";
$MY_SESS_CONN->Execute($sql);
return true;
} //end function
} ///:~
//利用 ADOdb 作为数据库笼统层。
require_once("adodb/adodb.inc.php");
//数据库设置装备摆设项,可放入设置装备摆设文件中(如:config.inc.php)。
$db_type = "mysql";
$db_host = "192.168.212.1";
$db_user = "sess_user";
$db_pass = "sess_pass";
$db_name = "sess_db";
//创立数据库毗连,这是一个全局变量。
$GLOBALS["MY_SESS_CONN"] =& ADONewConnection($db_type);
$GLOBALS["MY_SESS_CONN"]->Connect( $db_host, $db_user, $db_pass, $db_name);
//初始化 SESSION 设置,必需在 session_start() 之前运转!!
My_Sess::init();
?>
5、遗留成绩
假如网站的会见量很大的话,SESSION 的读写会频仍地对数据库停止操作,如许效力就会分明下降。思索到 SESSION 数据普通不会很大,可以测验考试用 C/Java 写个多线程的法式,用 HASH 表保留 SESSION 数据,并经由过程 socket 通讯停止数据读写,如许 SESSION 就保留在内存中,读写速度应当会快良多。别的还可以经由过程负载平衡来分管办事器负载。不外这些都只是我本人的一些设法和假定,并没有理论过 :(
从刚开始练习的PHP基础语法练习,到PHP语言在WEB中的应用,再到实际的项目开发,如留言版,相册系统,中小型公司网站系统,以及期间做过的有关团队合作的小游戏,让我受益匪浅,学到了很多。 |
|