|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
PHP于1994年由Rasmus Lerdorf创建,刚刚开始是Rasmus Lerdorf为了要维护个人网页而制作的一个简单的用Perl语言编写的程序。
这篇文章描写了如何定制php4的session处置。咱们供应一个如何写一个全功效的基于mysql数据库或dbm文件的session处置法式例子。
1、叙言
新的php4有一套本人的session处置函数。缺省情形下,每一个session存贮在体系一时目次的一个个自力文件中(例如在unix体系中为/tmp)。
这合适或不合适,依你的需求而言。例如:假如你的撑持php的web办事器散布在分歧的机械上,你不克不及很轻易地同享它们之间的session(固然,你也能够将sessions保留在NFS同享中)。另外一个潜伏的成绩是你机械上的数千或数百万个session文件使你的文件体系变得狼藉 。
对咱们来讲侥幸的是,php4的开辟者十分有远见(感激他们),他们为你我如许的用户供应了扩大session处置的接口。
这个文档注释一点session的处置而且供应两个可以任务的如何扩大session处置的例子。咱们的第一个例子将使session处置法式保留 session数据到DBM文件中。咱们的第二个例子将保留session数据到MYSQL数据库中。
在你入手下手之前,请下载ying20000602.zip 而且将它解开放到web文档目次中。(我已将它带在本文的开头处了)
任何一个咱们写的session处置法式会供应6个根基的函数,它们将被php4的session处置法式挪用,所以你不必忧虑如何挪用它们。
好在这些定制处置session的函数对你来讲是完整通明的。所以你可以修改它们而不会影响你本人的PHP剧本。
这几个函数是:
sess_open($sess_path, $session_name);
这个函数被session处置法式挪用来作初始化任务。需求传给它的两个参数是$sess_path,它对应你的php.ini文件中的session.save_path选项;$session_name,它对应php.ini中的session.name选项。它们详细如何任务,请看上面的例子。
sess_close();
这个函数在页面停止履行而且session处置法式需求封闭时被挪用。(注重,不要和sess_destory搅浑了,它是用来停止session的)
sess_read($key);
这个函数在session处置法式读取指定session键值($key)时。
这个函数检索并前往标识为$key的session数据.(注重:你不必忧虑如何序列化和反序列化数据,假如你不晓得这是甚么意思,不要忧虑它)
译者注:序列化是将变量或对象在法式停止或需求时保留在文件中,鄙人次法式运转或需求时再调入内存的手艺,有别于只保留数据的办法。
sess_write($key, $val);
这个函数据在session处置法式需求将数据保留时挪用,这类情形常常在你的法式停止时产生。
它担任将数据保留鄙人次能用sess_read($key)函数检索的中央。
sess_destroy($key);
这个函数在需求消毁session时。它担任删除session而且排除情况。
sess_gc($maxlifetime);
这个函数担任清算碎片。在这类情形下,它担任删除过时的session数据。session处置法式会偶然挪用它们。
如今咱们已清晰了咱们供应的函数。它们不长短要如许定名,但必需承受这些参数。(不论你需不需求它们)
DBM session 处置法式
咱们的第一个典范是写一个保留session数据到DBM文件中的定制session处置法式。(这是ying20000602.zip中的session_dbm.php文件)
有良多充分的来由让你要如许做,例如,假如你在isp那儿有一台同享的办事器(译注:相当于咱们说的虚拟主机吧)而且你不想让你的session数据
和他人的混在一同。
主要正文:
在你实验这些法式时你的php4必需有DBM撑持。假如不是如许的(译注:假如没有DBM撑持)会很好看,真的很好看!
咱们要做的这些任务将会失掉一个一切session数据的DBM文件。(万一你不晓得,DBM文件象一个仅保留"键/值"对的十分复杂的数据库.
由上面的6个函数据完成:
sess_open($sess_path, $session_name);
咱们将挪用dbmopen()翻开一个处于读写形式的DBM文件。咱们的DBM文件将被定名为/tmp/PHPSESSID,除非你修正了php.ini中的session路
径和名字设置。
sess_close();
在这个函数中,咱们将复杂地挪用dbmclose()函数封闭DBM文件。
sess_read($key);
这儿咱们仅仅挪用dbmfetch()载入和参数$key相干连的session数据。
在载入一个session时,咱们需求包管读入的不是一个过时数据,所以咱们必需给session配上一个工夫标志。
为何?由于在它们生效,不论甚么缘由而没有被删失落时,咱们不会心外埠读入过时数据。这会是一个很大的忌讳。
咱们晓得DBM文件只保留 键/值 对,因而不能不在写session数据时将工夫标志同" 值"一同写入,在读session数据时去失落。
任何已过时的session将被疏忽。看看这个源法式,它会让你更清晰。
sess_write($key, $val);
写入一个session,咱们会利用dbmreplace()函数。注重,从上所述咱们要保留过时工夫标志在session中,所以咱们要将工夫标志绑到值上。
sess_destroy($key);
消毁一个session很轻易,咱们只需求挪用dbmdelete()函数将它从session文件中删除。
sess_gc($maxlifetime);
过时数据搜集在这儿有点使人厌恶但倒是必须的,为了到达目标咱们在轮回扫描一切保留在DBM文件中的session而且删失落过时的。这会很慢因
为咱们轮回经由过程一切保留在这个文件中的一切session数据。
如今咱们已有了一个DBM session处置法式,太酷了!
如今,咱们让这些session保留到mysql数据库中。
Mysql session处置法式
(This
咱们的下一个典范是写一个将session数据存到mysql数据库的定制session处置法式。(这个在session_mysql.php文件中,见文章尾部)
在你有很多撑持PHP的办事器而且你需求同享它们之间的session时你会想将session保留在数据库中的。(好比你办事于良多用户而且需求
负载均衡时)
You have a bunch of machines doing web/PHP stuff, a machine serving
你有一批机械作撑持php的办事器,需求一台机械作你的通俗数据库办事器,别的一台运转mysql数据库处置session。仅如许对大多半人来
说就具有很大的杀伤力的。:)(译注:能够意思是太酷了吧)
主要提醒:
在你实验之前你的php必需撑持mysql。(译注:这好象已不成成绩了,php如今已内建mysql撑持了)假如不是如许的话,工作会很好看,真的
很好看。
起首咱们在mysql中创立一个session数据库,而且创立一个session表。先运转你的mysql客户端而且运转上面的号令:
mysql> CREATE DATABASE sessions;
mysql> GRANT select, insert, update, delete ON sessions.* TO phpsession@localhost
-> IDENTIFIED BY 'phpsession';
mysql> CREATE TABLE sessions (
-> sesskey char(32) not null,
-> expiry int(11) unsigned not null,
-> value text not null,
-> PRIMARY KEY (sesskey)
-> );
下一步,修正session_mysql.php文件的$SESS_DB* 变量使其婚配你机械上的数据库设置。在你持续之前确信一切看起来优秀。
咱们的6个函数会依托mysql数据库任务:
sess_open($sess_path, $session_name);
咱们需求挪用mysql_Pconnect(),然后用mysql_selsect_db()选择session数据库 。$sess_path 和$session_name 参数
是有关的但咱们不能不保存它们。(译注:原文如斯,多是为了兼容吧)
sess_close();
咱们要翻开一个mysql永世毗连因而咱们在这个函数中不做任何事。(一个空函数)
sess_read($key);
这个诀窍就是一个复杂的select语句,咱们想要读取所给的$key的session数据,需求指定过时工夫信息。
sess_write($key, $val);
写session数据用了一个小幻术。咱们起首试图用insert语句保留session数据到数据库中。假如掉败(主键束缚)则意味着这个key已写入,然后咱们
不能不用一update语句取代。
sess_destroy($key);
删除一个session很轻易,咱们只需求从数据库中删除这个键值。
sess_gc($maxlifetime);
处置过时session也很轻易,咱们只需求从数据库中删除过时session().
作为停止这个小教程,但愿你在扩大php4的session处置时有个好感到。
这个典范只是复杂的示范了你如何做才干扩大它们使其顺应你的需求,假如你找到甚么bug的话,请让我晓得:)
faq:
假如你忧虑session文件在/tmp目次中和其余虚拟机搅浑,正好将它们存到别处。
这就是为何有session.save_path选项的缘由。
假如你忧虑功能的话你可以思索将session存在同享内存中。你只需求在编译php时加上MM撑持(--with-mm)并指定sessio.save_handler 为 mm
在.htaccess中,php.ini中或httpd.conf中。
我感觉只要多台机械要保留session时才会用到数据库。
(最初这句其实欠好译,自已看吧)
session_dbm.php
=========================================================================
<?
/* ------------------------------------------------------------------------
* session_dbm.php
* ------------------------------------------------------------------------
* PHP4 DBM Session Handler
* Version 1.00
* by Ying Zhang (ying@zippydesign.com)
* Last Modified: May 21 2000
*
* ------------------------------------------------------------------------
* TERMS OF USAGE:
* ------------------------------------------------------------------------
* You are free to use this library in any way you want, no warranties are
* expressed or implied. This works for me, but I don't guarantee that it
* works for you, USE AT YOUR OWN RISK.
*
* While not required to do so, I would appreciate it if you would retain
* this header information. If you make any modifications or improvements,
* please send them via email to Ying Zhang <ying@zippydesign.com>.
*
* ------------------------------------------------------------------------
* DESCRIPTION:
* ------------------------------------------------------------------------
* This library tells the PHP4 session handler to write to a DBM file
* instead of creating individual files for each session.
*
* ------------------------------------------------------------------------
* INSTALLATION:
* ------------------------------------------------------------------------
* Make sure you have DBM support compiled into PHP4. Then copy this
* script to a directory that is accessible by the rest of your PHP
* scripts.
*
* ------------------------------------------------------------------------
* USAGE:
* ------------------------------------------------------------------------
* Include this file in your scripts before you call session_start(), you
* don't have to do anything special after that.
*/
$SESS_DBM = "";
$SESS_LIFE = get_cfg_var("session.gc_maxlifetime");
function sess_open($save_path, $session_name) {
global $SESS_DBM;
$SESS_DBM = dbmopen("$save_path/$session_name", "c");
return ($SESS_DBM);
}
function sess_close() {
global $SESS_DBM;
dbmclose($SESS_DBM);
return true;
}
function sess_read($key) {
global $SESS_DBM, $SESS_LIFE;
$var = "";
if ($tmp = dbmfetch($SESS_DBM, $key)) {
$expires_at = substr($tmp, 0, strpos($tmp, "|"));
if ($expires_at > time()) {
$var = substr($tmp, strpos($tmp, "|") + 1);
}
}
return $var;
}
function sess_write($key, $val) {
global $SESS_DBM, $SESS_LIFE;
dbmreplace($SESS_DBM, $key, time() + $SESS_LIFE . "|" . $val);
return true;
}
function sess_destroy($key) {
global $SESS_DBM;
dbmdelete($SESS_DBM, $key);
return true;
}
function sess_gc($maxlifetime) {
global $SESS_DBM;
$now = time();
$key = dbmfirstkey($SESS_DBM);
while ($key) {
if ($tmp = dbmfetch($SESS_DBM, $key)) {
$expires_at = substr($tmp, 0, strpos($tmp, "|"));
if ($now > $expires_at) {
sess_destroy($key);
}
}
$key = dbmnextkey($SESS_DBM, $key);
}
}
session_set_save_handler(
"sess_open",
"sess_close",
"sess_read",
"sess_write",
"sess_destroy",
"sess_gc");
?>
=====================================================================================
session_mysql.php
=======================================================================================
<?
/* ------------------------------------------------------------------------
* session_mysql.php
* ------------------------------------------------------------------------
* PHP4 MySQL Session Handler
* Version 1.00
* by Ying Zhang (ying@zippydesign.com)
* Last Modified: May 21 2000
*
* ------------------------------------------------------------------------
* TERMS OF USAGE:
* ------------------------------------------------------------------------
* You are free to use this library in any way you want, no warranties are
* expressed or implied. This works for me, but I don't guarantee that it
* works for you, USE AT YOUR OWN RISK.
*
* While not required to do so, I would appreciate it if you would retain
* this header information. If you make any modifications or improvements,
* please send them via email to Ying Zhang <ying@zippydesign.com>.
*
* ------------------------------------------------------------------------
* DESCRIPTION:
* ------------------------------------------------------------------------
* This library tells the PHP4 session handler to write to a MySQL database
* instead of creating individual files for each session.
*
* Create a new database in MySQL called "sessions" like so:
*
* CREATE TABLE sessions (
* sesskey char(32) not null,
* expiry int(11) unsigned not null,
* value text not null,
* PRIMARY KEY (sesskey)
* );
*
* ------------------------------------------------------------------------
* INSTALLATION:
* ------------------------------------------------------------------------
* Make sure you have MySQL support compiled into PHP4. Then copy this
* script to a directory that is accessible by the rest of your PHP
* scripts.
*
* ------------------------------------------------------------------------
* USAGE:
* ------------------------------------------------------------------------
* Include this file in your scripts before you call session_start(), you
* don't have to do anything special after that.
*/
$SESS_DBHOST = "localhost"; /* database server hostname */
$SESS_DBNAME = "sessions"; /* database name */
$SESS_DBUSER = "phpsession"; /* database user */
$SESS_DBPASS = "phpsession"; /* database password */
$SESS_DBH = "";
$SESS_LIFE = get_cfg_var("session.gc_maxlifetime");
function sess_open($save_path, $session_name) {
global $SESS_DBHOST, $SESS_DBNAME, $SESS_DBUSER, $SESS_DBPASS, $SESS_DBH;
if (! $SESS_DBH = mysql_pconnect($SESS_DBHOST, $SESS_DBUSER, $SESS_DBPASS)) {
echo "<li>Can't connect to $SESS_DBHOST as $SESS_DBUSER";
echo "<li>MySQL Error: ", mysql_error();
die;
}
if (! mysql_select_db($SESS_DBNAME, $SESS_DBH)) {
echo "<li>Unable to select database $SESS_DBNAME";
die;
}
return true;
}
function sess_close() {
return true;
}
function sess_read($key) {
global $SESS_DBH, $SESS_LIFE;
$qry = "SELECT value FROM sessions WHERE sesskey = '$key' AND expiry > " . time();
$qid = mysql_query($qry, $SESS_DBH);
if (list($value) = mysql_fetch_row($qid)) {
return $value;
}
return false;
}
function sess_write($key, $val) {
global $SESS_DBH, $SESS_LIFE;
$expiry = time() + $SESS_LIFE;
$value = addslashes($val);
$qry = "INSERT INTO sessions VALUES ('$key', $expiry, '$value')";
$qid = mysql_query($qry, $SESS_DBH);
if (! $qid) {
$qry = "UPDATE sessions SET expiry = $expiry, value = '$value' WHERE sesskey = '$key' AND expiry > " . time();
$qid = mysql_query($qry, $SESS_DBH);
}
return $qid;
}
function sess_destroy($key) {
global $SESS_DBH;
$qry = "DELETE FROM sessions WHERE sesskey = '$key'";
$qid = mysql_query($qry, $SESS_DBH);
return $qid;
}
function sess_gc($maxlifetime) {
global $SESS_DBH;
$qry = "DELETE FROM sessions WHERE expiry < " . time();
$qid = mysql_query($qry, $SESS_DBH);
return mysql_affected_rows($SESS_DBH);
}
session_set_save_handler(
"sess_open",
"sess_close",
"sess_read",
"sess_write",
"sess_destroy",
"sess_gc");
?>
=========================================================================
test.php
==========================================================================
<?
/* ------------------------------------------------------------------------
* test.php
* ------------------------------------------------------------------------
* PHP4 Customer Session Handler Test Script
* Version 1.00
* by Ying Zhang (ying@zippydesign.com)
* Last Modified: May 21 2000
*/
/* default to DBM handler */
if (! isset($handler)) {
$handler = "dbm";
}
/* default action is increment */
if (! isset($action)) {
$action = "increment";
}
/* load up the appropriate session handling script, depending on the handler */
if ($handler == "dbm") {
include("session_dbm.php");
} elseif ($handler == "mysql") {
include("session_mysql.php");
} else {
echo "<li>Unrecognized handler ($handler)";
die;
}
/* start the session and register a simple counter */
session_start();
session_register("count");
/* figure out what we should do, depending on the action */
switch ($action) {
case "increment" :
$count = isset($count) ? $count + 1 : 0;
break;
case "destroy" :
session_destroy();
break;
case "gc" :
$maxlife = get_cfg_var("session.gc_maxlifetime");
sess_gc($maxlife);
break;
default:
echo "<li>Unknown action ($action)";
break;
}
?>
<h1>Session Test Script</h1>
<ul>
<li>Handler: <b><?=$handler?></b>
<li>Action: <b><?=$action?></b>
<li>Count: <b><?=$count?></b>
</ul>
<hr size=1>
<form>
<table>
<tr>
<td>Handler:</td>
<td>
<select name="handler">
<option value="dbm">DBM</option>
<option value="mysql">MySQL</option>
</select>
</td>
</tr>
<tr>
<td>Action:</td>
<td>
<select name="action">
<option value="increment">Increment</option>
<option value="destroy">Session Destroy</option>
<option value="gc">Force Garbage Collection</option>
</select>
</td>
</tr>
<tr>
<td></td>
<td><br><input type="submit"></td>
</tr>
</table>
</form>
如果你单纯是为了做网站赚钱,我想你还是别学php的好,去学ASP,JSP好了,毕竟它们有实力雄厚的公司去支持它们。 |
|