首页 >后端开发 >php教程 >跨页面读取数据库session失败

跨页面读取数据库session失败

WBOY
WBOY原创
2016-06-23 14:03:331038浏览

要疯了。。三天了。。一个问题就是搞不定。不知道问谁去。
问题如下:
我在set_session_test.php中注册的session无法再get_session_php中读取,也就是只能读取当天页面的session。。。为神马???求神人解释。高分求救。



数据库结构如下:

conf.php

<?phpdefine("DBHOST", "localhost");define("DBUSER", "root");define("DBPSW", "");define("DBNAME", "savesession");define("PAGENUM",10);


final_session.php
<?php$gb_DBname = "savesession";$gb_DBuser = "root";$gb_DBpass = "";$gb_DBHOSTname = "localhost";$SESS_DBH = "";$SESS_LIFE = get_cfg_var("session.gc_maxlifetime");function sess_open($save_path, $session_name){	global $gb_DBname,$gb_DBuser,$gb_DBpass,$gb_DBHOSTname,$SESS_DBH;	if(!$SESS_DBH = mysql_pconnect($gb_DBHOSTname,$gb_DBuser,$gb_DBpass)){		echo "<li>Mysql Error:".mysql_errno()."</li>";		die();	}		if(!mysql_select_db($gb_DBname)){		echo "<li>Mysql Error:".mysql_errno()."</li>";		die();	}		return true;}function sess_close(){	return true;}function sess_read($key){	global $SESS_DBH,$SESS_LIFE;		$qry = "SELECT * FROM db_session 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 = $val;	$qry = "INSERT INTO db_session VALUES('$key', $expiry, '$value')";	//echo $qry;	$qid = mysql_query($qry,$SESS_DBH);	if(!$qid){		$qry = "UPDATE db_session SET expiry=$expiry,value='$value' WHERE sesskey='$key' and expiry>".time();		$qid = mysql_query($qry);	}	return $qid;}function sess_destory($key){	global $SESS_DBH;		$qry = "DELETE FROM db_session WHERE sesskey = '$key'";	$qid = mysql_query($qry, $SESS_DBH);	return $qid;}function sess_gc($maxlifetime){	global $SESS_DBH;		$qry = "DELETE FROM db_session WHERE expiry<".time();	$qid = mysql_query($qry, $SESS_DBH);	return mysql_affected_rows($SESS_DBH);}session_module_name();session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destory", "sess_gc");


set_session_test.php
<?phpinclude_once 'final_session.php';session_start();$_SESSION['message'] = "Can I help you?";$_SESSION['message1'] = "No, Thank ";$_SESSION['Tom'] = "Tom";echo $_SESSION['message'];echo $_SESSION['message1'];echo $_SESSION['Tom'];echo "<a href=\"get_session_test.php\">显示SESSION</a>";?>


get_session_test.php
<?phpinclude_once 'final_session.php';session_start();$_SESSION['test'] = "test";echo $_SESSION['test'];$_SESSION['test2'] = "test22222222222";echo $_SESSION['test2'];echo $_SESSION['message'];echo $_SESSION['message1'];echo $_SESSION['Tom'];?>


回复讨论(解决方案)

session_set_save_handler()
注意:使用本函数前,先要配置php.ini文件,session.save_hadler=user ,否则,session_set_save_handler()不会生效。

session_set_save_handler()
注意:使用本函数前,先要配置php.ini文件,session.save_hadler=user ,否则,session_set_save_handler()不会生效。

有试过。。也用ini_set()函数设置了。。结果依然是这样的。。。数据库中是有session写入的。。

if(list($value) = mysql_fetch_row($qid)){
????

你查询的是全部字段,为什么只取出第一个?
那不是 sessionid 吗?

把sess_read里的

$qry = "SELECT * FROM db_session WHERE sesskey = '$key' and expiry > ".time();

换成
$qry = "SELECT value FROM db_session WHERE sesskey = '$key' and expiry > ".time();

就可以了。 

你试用cookie看可以解决你的问题吗。

楼主$_SESSION['message'] = "Can I help you?";
输出变量看看。echo $_SESSION['message'];

.......
试了了一下 楼主的代码 ...

依然木有正解。

难道木有高人了?

这比我那个页内传值的问题高深多了,我只不过想把表单输入的内容都存储下来 ,想什么时候用旧什么时候用,这个功能比我那个全多了。。。时刻关注。

还有一处

function sess_write($key, $val){    global $SESS_DBH,$SESS_LIFE;        $expiry = time()+$SESS_LIFE;    $value = $val;    $qry = "REPLACE INTO db_session VALUES('$key', $expiry, '$value')";    $qid = mysql_query($qry,$SESS_DBH);}

好的。。我去试下。。但感觉应该不是这个问题。。因为session已经成功写入。。是读取的问题。

还有一处
PHP code
function sess_write($key, $val){
    global $SESS_DBH,$SESS_LIFE;
    
    $expiry = time()+$SESS_LIFE;
    $value = $val;
    $qry = "REPLACE INTO db_session VALUES('$key', $expiry, ……

还是不行。。。不过学会了REPLACE的用法。。受教了。

等待高人解决。。另外本人贴张图上来。好让大家明白究竟什么样的存储结构。


好的。。我去试下。。但感觉应该不是这个问题。。因为session已经成功写入。。是读取的问题。

引用 11 楼  的回复:

还有一处
PHP code
function sess_write($key, $val){
global $SESS_DBH,$SESS_LIFE;

$expiry = time()+$SESS_LIFE;
$value = $val;
$qr……

加分悬赏。提供正解者。加分100.

SESSIONID($key)是保存在COOKIE里的,有没有设置它的保存时间呢?
能确保再次访问的时候能拿到跟前次访问相同的$key?

怎么还没搞好呢?
这是我改写的你的代码。
因为我不喜欢用全局变量改成了常量,另外改了一下库名和表名

<?phpdefine("DBHOST", "localhost");define("DBUSER", "root");define("DBPSW", "");define("DBNAME", "test");define("PAGENUM",10);define("SESS_LIFE", get_cfg_var("session.gc_maxlifetime"));function sess_open($save_path, $session_name){    if(! $conn = mysql_pconnect(DBHOST, DBUSER, DBPSW)){        echo "<li>Mysql Error:".mysql_errno()."</li>";        die();    }    define("SESS_DBH", $conn);    if(!mysql_select_db(DBNAME, SESS_DBH)){        echo "<li>Mysql Error:".mysql_errno()."</li>";        die();    }    return true;}function sess_close(){    return true;}function sess_read($key){    $qry = "SELECT * FROM sessions WHERE sesskey = '$key' and expiry > ".time();    $qid = mysql_query($qry, SESS_DBH) or die(mysql_error());        $r = mysql_fetch_assoc($qid);    return $r['value'];}function sess_write($key, $val){    $expiry = time()+SESS_LIFE;    $value = $val;    $qry = "REPLACE INTO sessions VALUES('$key', $expiry, '$value')";    $qid = mysql_query($qry, SESS_DBH);}function sess_destory($key){    $qry = "DELETE FROM sessions WHERE sesskey = '$key'";    $qid = mysql_query($qry, SESS_DBH);    return $qid;}function sess_gc($maxlifetime){    $qry = "DELETE FROM sessions WHERE expiry<".time();    $qid = mysql_query($qry, SESS_DBH);    return mysql_affected_rows(SESS_DBH);}//session_module_name();session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destory", "sess_gc");session_start();

sess_read里的  

  if(list($value) = mysql_fetch_row($qid)){        return $value;    }

错了,只需要返回session的序列化串,也就是表内的value字段,改成
    if($value = mysql_fetch_row($qid)){        return $value[2];    }

严重感谢。。。代码测试可以正常运行。。但我还是想知道是神马毛病。
怎么还没搞好呢?
这是我改写的你的代码。
因为我不喜欢用全局变量改成了常量,另外改了一下库名和表名
PHP code
define("DBHOST", "localhost");
define("DBUSER", "root");
define("DBPSW", "");
define("DBNAME", "test");
define("PAGENUM",10);
defi……

那段代码木有问题。。测试过。。换了结果还是一样的。
sess_read里的  
PHP code
  if(list($value) = mysql_fetch_row($qid)){
        return $value;
    }

错了,只需要返回session的序列化串,也就是表内的value字段,改成
PHP code
    if($value = mysql_fetch_row($qid)){
        re……

100分送你了。。。稍等我看下能不能找出什么毛病。。这两天就结贴。
怎么还没搞好呢?
这是我改写的你的代码。
因为我不喜欢用全局变量改成了常量,另外改了一下库名和表名
PHP code
define("DBHOST", "localhost");
define("DBUSER", "root");
define("DBPSW", "");
define("DBNAME", "test");
define("PAGENUM",10);
defi……

因为你的表中的sesskey列没有设为主键或惟一约束,所以在每次在session_start();会产生一个一样的SID,把数据库表sesskey列设置为主键或惟一键即可解决。

注:你多刷新几次你的测试代码,然后去数据库查一下会发现有多个重复的SID

我的数据库是有设主键的。。你说的情况我明白。但不是这种情况。
我有个回帖里面也提到了这个问题。
数据库的写入是没有问题的。。可以正常插入。

但是你设的主键是不是(sesskey和expiry),而不是sesskey吧???

不是组合主键。。。主键只有sesskey....
但是你设的主键是不是(sesskey和expiry),而不是sesskey吧???

问题可能出在:

function sess_read($key){
    $qry = "SELECT * FROM sessions WHERE sesskey = '$key' and expiry > ".time();

你把$qry打印出来,看看能不能取到?

sess_read里的  

数据库读出来后 只能返回value字段里面的数据! 不能返回整条数据

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn