现在我对自己编写的会话类有一个奇怪的问题,该脚本用于检查用户是否仍然登录并保持会话完好无损,但我觉得我的脚本写得不好而不是计划得好 - 我确实需要真正澄清如何改进此脚本,并确保在用户退出之前始终将会话分配给正确的用户。
我遇到的主要问题是$session->user_id
不断更改为1
,这是users表中的第一个用户。即使退出并在几次刷新后,它也会更改为1
,但我不知道为什么会这样做。
当用户想要注销时,它会清除所有Cookie并使用新会话重置所有Cookie,但user_id
始终为0
但是在一次刷新后,它会更改为{{1} }。
我正在使用的脚本:
1
在<?php
class session
{
var $session_id = '';
var $browser = '';
var $ip = '';
var $isp = '';
var $time_now = 0;
var $cookie_data = '';
var $cookie_store = array();
var $user_id = 0;
var $user_info = array();
function session_begin()
{
global $db;
$this->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? $db->sql_escape($_SERVER['REMOTE_ADDR']) : '';
$this->isp = (!empty($this->ip)) ? gethostbyip($this->ip) : '';
if(isset($_SESSION[COOKIE_NAME]) || isset($_SESSION[COOKIE_NAME]))
{
if(isset($_SESSION[COOKIE_NAME]))
{
$stored_session = $_SESSION[COOKIE_NAME];
}
elseif(isset($_COOKIE[COOKIE_NAME]))
{
$stored_session = $_COOKIE[COOKIE_NAME];
}
$this->session_id = $stored_session;
$sql = "SELECT " . SESSIONS_TABLE . ".*,
" . MEMBERS_TABLE . ".uid
FROM " . SESSIONS_TABLE . ",
" . MEMBERS_TABLE . "
WHERE " . SESSIONS_TABLE . ".session_id = '" . $db->sql_escape($stored_session) . "'
LIMIT 1";
$result = $db->sql_query($sql);
if($db->sql_numrows($result) == 1)
{
while($row = $db->sql_fetchrow($result))
{
if($row['uid'] == 0)
{
$this->user_id = 0;
}
else
{
$this->user_info['uid'] = $this->user_id = $row['uid'];
}
$this->user_info['sid'] = $row['session_id'];
$this->user_info['browser'] = $row['session_browser'];
$this->user_info['ip'] = $row['session_ip'];
$this->user_info['isp'] = $row['session_isp'];
}
if($this->user_info['sid'] == $this->session_id)
{
//echo 'yes';
}
else
{
$this->session_restart();
}
}
else
{
$sql = "INSERT INTO " . SESSIONS_TABLE . "
(session_id, session_user_id, session_start, session_ip, session_isp, session_browser)
VALUES ('" . $this->session_id . "', '" . $this->user_id . "', '" . time() . "', '" . $this->ip . "', '" . $this->isp . "', 'wtf')";
$result = $db->sql_query($sql);
}
}
else
{
$_SESSION[COOKIE_NAME] = $this->session_id = $this->generate_session_id(32);
setcookie(COOKIE_NAME, $this->session_id, time()+3600*9000*9000, '/');
}
}
function session_restart()
{
if(isset($_COOKIE[COOKIE_NAME]))
{
setcookie(COOKIE_NAME, NULL, time()-3600);
}
$this->user_id = 0;
$this->session_id = $this->generate_session_id(32);
if(setcookie(COOKIE_NAME, $this->session_id, time()+3600*9000*9000, '/'))
{
return true;
}
else
{
return false;
}
}
function generate_session_id($limit = 32, $symbols = false)
{
$string = 'a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|';
if($symbols == true)
{
$string .= '$|@|_|-|+';
}
$ary = explode('|', $string);
$link = '';
shuffle($ary);
foreach($ary as $letter)
{
$link .= $letter . rand(0, 9);
}
if(!empty($limit) || $limit != 10)
{
return substr($link, -$limit);
}
else
{
return substr($link, -10);
}
}
}
?>
中调用$session->session_begin()
,每次页面刷新完成时调用header.php
。只有在发生注销或用户详细信息与数据库中的会话详细信息不匹配时才会调用$session->session_restart()
。
我真的没有很好的潜在知识如何创建一个好的脚本来保持会话保存并分配给合适的用户 - 当我编写类似这样的内容以及如何保持良好的编写时,我开始感到困惑...... < / p>
答案 0 :(得分:2)
这可能听起来很苛刻,但你需要抛弃脚本。它阻碍了你!
PHP built-in session handling extensive configuration options。实际上,您实际上是在自己的代码中使用它...然后您添加了不必要的复杂层。
调用脚本顶部的session_start
以打开会话。 PHP将完成剩下的工作。它将使用它自己的cookie跟踪用户。您可以使用配置设置所有cookie选项。
要记录用户,只需在$_SESSION
数组中设置一个值,就像您现在正在做的那样。您作为类的属性保留的所有内容 - 用户ID,用户代理和IP等 - 都可以存储在数组中。登录/注销时甚至可以regenerate the session id,就像您当前的代码一样。