千家信息网

如何实现PHP独立Session数据库存储操作类

发表于:2025-02-24 作者:千家信息网编辑
千家信息网最后更新 2025年02月24日,这篇文章将为大家详细讲解有关如何实现PHP独立Session数据库存储操作类,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。直接上代码:class DbSession
千家信息网最后更新 2025年02月24日如何实现PHP独立Session数据库存储操作类

这篇文章将为大家详细讲解有关如何实现PHP独立Session数据库存储操作类,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

直接上代码:

class DbSession
{

const TYPE_INT = 1;
const TYPE_STR = 2;

/**
* Database configration
*
* @var array
*/
private $_config = array(
'host' => '127.0.0.1′,
'port' => 3306,
'username' => 'root',
'password' => 'root',
'dbname' => 'db_mylab',
'tablename' => 't_sessions',
'cookie_prefix' => 'mylab_',
'cookiepath' => '/',
'cookiedomain' => ",
'cookie_timeout' => 900
);

/**
* Table fields type array
*
* @var array
*/
private $_db_fields = array(
'crc32sid' => self::TYPE_INT,
'sessionhash' => self::TYPE_STR,
'idhash' => self::TYPE_STR,
'userid' => self::TYPE_INT,
'ipaddress' => self::TYPE_STR,
'lastactivity' => self::TYPE_STR,
'location' => self::TYPE_STR,
'loggedin' => self::TYPE_INT,
'heartbeat' => self::TYPE_STR
);

/**
* db obj
*
* @var mysqli object
*/
private $_mysqli = null;

/**
* Weather the session was created or existed previously
*
* @var bool
*/
private $_created = false;

/**
* Array of changes.
*
* @var array
*/
private $_changes = array();

/**
* @var bool
*/

private $_db_inited = false;

/**
* session host
*
* @var string
*/
private $_session_host = ";

/**
* session idhash
*
* @var string
*/
private $_session_idhash = ";

private $_dbsessionhash = ";

private $_vars = array();

public function __construct()
{
$this->_dbsessionhash = addslashes($this->get_cookie('sessionhash'));

$this->_session_host = substr($_SERVER['REMOTE_ADDR'], 0, 15);

#This should *never* change during a session
$this->_session_idhash = md5($_SERVER['HTTP_USER_AGENT'] . self::fetch_substr_ip(self::fetch_alt_ip()) );

$this->_init_config();
$this->init_db();

$gotsession = false;

if ($this->_dbsessionhash)
{
$sql = '
SELECT *
FROM ' . $this->_config['tablename'] . '
WHERE crc32sid = ' . sprintf('%u', crc32($this->_dbsessionhash)) . '
AND sessionhash = '' . $this->_dbsessionhash . ''
AND idhash = '' . $this->_session_idhash . ''
AND heartbeat > '' . date('Y-m-d H:i:s' ,TIMENOW - $this->_config['cookie_timeout']) . ''';
//echo $sql;exit;
$result = $this->_mysqli->query($sql);
$session = $result->fetch_array(MYSQLI_ASSOC);

if ($session AND ($this->fetch_substr_ip($session['ipaddress']) == $this->fetch_substr_ip($this->_session_host)))
{
$gotsession = true;
$this->_vars = $session;
$this->_created = false;
}
}

if ($gotsession == false)
{
$this->_vars = $this->fetch_session();
$this->_created = true;
$gotsession = true;
}

if ($this->_created == false)
{
$this->set('lastactivity', date('Y-m-d H:i:s', TIMENOW));
$this->set('location', $_SERVER['REQUEST_URI']);
}

}

/**
* Builds an array that can be used to build a query to insert/update the session
*
* @return array Array of column name => prepared value
*/
private function _build_query_array()
{
$return = array();
foreach ($this->_db_fields AS $fieldname => $cleantype)
{
switch ($cleantype)
{
case self::TYPE_INT:
$cleaned = is_numeric($this->_vars["$fieldname"]) ? $this->_vars["$fieldname"] : intval($this->_vars["$fieldname"]);
break;
case self::TYPE_STR:
default:
$cleaned = "'" . addslashes($this->_vars["$fieldname"]) . "'";
}
$return["$fieldname"] = $cleaned;
}

return $return;
}

/**
* Sets a session variable and updates the change list.
*
* @param string Name of session variable to update
* @param string Value to update it with
*/
public function set($key, $value)
{
if ($this->_vars["$key"] != $value)
{
$this->_vars["$key"] = $value;
$this->_changes["$key"] = true;
}
}

public function get($key)
{
return $this->_vars["$key"];
}

public function unsetchangedvar($var)
{
if (isset($this->_changes["$var"]))
{
unset($this->_changes["$var"]);
}
}

/**
* Fetches a valid sessionhash value, not necessarily the one tied to this session.
*
* @return string 32-character sessionhash
*/
static function fetch_sessionhash()
{
return hash('md5′ , TIMENOW . rand(1, 100000) . uniqid() );
}

private function _init_config()
{
$registry = Zend_Registry::getInstance();
$config = $registry->get('config');
$this->_config['host'] = $config->database->params->host;
$this->_config['port'] = $config->database->params->port;
$this->_config['username'] = $config->database->params->username;
$this->_config['password'] = $config->database->params->password;
$this->_config['dbname'] = $config->database->params->dbname;
$this->_config['tablename'] = $config->database->session->tablename;

}

/**
* initialize database connection
*/
public function init_db()
{
if ($this->_db_inited)
{
return true;
}

//mysqli_report(MYSQLI_REPORT_OFF);

$this->_mysqli = new mysqli(
$this->_config['host'],
$this->_config['username'],
$this->_config['password'],
$this->_config['dbname'],
$this->_config['port']
);

/* check connection */
if (mysqli_connect_errno())
{

// printf("Connect failed: %sn", mysqli_connect_error());
// echo 'in ', __FILE__, ' on line ', __LINE__;
echo "{ success: false, errors: { reason: ' Connect failed: " . addslashes( mysqli_connect_error() ) . "' }}";
exit();

}

$this->_mysqli->query('set names latin1′);
$this->_db_inited = true;

return true;
}

/**
* Fetches an alternate IP address of the current visitor, attempting to detect proxies etc.
*
* @return string
*/
static function fetch_alt_ip()
{
$alt_ip = $_SERVER['REMOTE_ADDR'];

if (isset($_SERVER['HTTP_CLIENT_IP']))
{
$alt_ip = $_SERVER['HTTP_CLIENT_IP'];
}
else if (isset($_SERVER['HTTP_FROM']))
{
$alt_ip = $_SERVER['HTTP_FROM'];
}

return $alt_ip;
}

/**
* Returns the IP address with the specified number of octets removed
*
* @param string IP address
*
* @return string truncated IP address
*/
static function fetch_substr_ip($ip, $length = null)
{
return implode('.', array_slice(explode('.', $ip), 0, 4 - $length));
}

/**
* Fetches a default session. Used when creating a new session.
*
* @param integer User ID the session should be for
*
* @return array Array of session variables
*/
public function fetch_session($userid = 0)
{
$sessionhash = self::fetch_sessionhash();

$this->set_cookie('sessionhash', $sessionhash);

return array(
'crc32sid' => sprintf('%u', crc32($sessionhash)),
'sessionhash' => $sessionhash,
'idhash' => $this->_session_idhash,
'userid' => $userid,
'ipaddress' => $this->_session_host,
'lastactivity' => date('Y-m-d H:i:s', TIMENOW),
'location' => $_SERVER['REQUEST_URI'],
'loggedin' => $userid ? 1 : 0,
'heartbeat' => date('Y-m-d H:i:s', TIMENOW)
);
}

public function get_cookie($cookiename)
{
$full_cookiename = $this->_config['cookie_prefix'] . $cookiename;

if (isset($_COOKIE[$full_cookiename]))
{
return $_COOKIE[$full_cookiename];
}
else
{
return false;
}
}

public function set_cookie($name, $value = ", $permanent = 1, $allowsecure = true)
{

if ($permanent)
{
$expire = TIMENOW + 60 * 60 * 24 * 365;
}
else
{
$expire = 0;
}

if ($_SERVER['SERVER_PORT'] == '443′)
{
// we're using SSL
$secure = 1;
}
else
{
$secure = 0;
}

// check for SSL
$secure = ((REQ_PROTOCOL === 'https' AND $allowsecure) ? true : false);

$name = $this->_config['cookie_prefix'] . $name;
$filename = 'N/A';
$linenum = 0;

if (!headers_sent($filename, $linenum))
{ // consider showing an error message if there not sent using above variables?
if ($value == " AND strlen($this->_config['cookiepath']) > 1 AND strpos($this->_config['cookiepath'], '/') !== false)
{
// this will attempt to unset the cookie at each directory up the path.
// ie, cookiepath = /test/abc/. These will be unset: /, /test, /test/, /test/abc, /test/abc/
// This should hopefully prevent cookie conflicts when the cookie path is changed.
$dirarray = explode('/', preg_replace('#/+$#', ", $this->_config['cookiepath']));
$alldirs = ";
foreach ($dirarray AS $thisdir)
{
$alldirs .= "$thisdir";
if (!empty($thisdir))
{ // try unsetting without the / at the end
setcookie($name, $value, $expire, $alldirs, $this->_config['cookiedomain'], $secure);
}
$alldirs .= "/";
setcookie($name, $value, $expire, $alldirs, $this->_config['cookiedomain'], $secure);
}
}
else
{
setcookie($name, $value, $expire, $this->_config['cookiepath'], $this->_config['cookiedomain'], $secure);
}
}
else if (!DEBUG)
{
echo "can't set cookies";
}
}

private function _save()
{
$cleaned = $this->_build_query_array();

if ($this->_created)
{
//var_dump($cleaned);
# insert query
$this->_mysqli->query('
INSERT IGNORE INTO ' . $this->_config['tablename'] . '
(' . implode(',', array_keys($cleaned)) . ')
VALUES
(' . implode(',', $cleaned). ')
');
}
else
{
# update query
$update = array();

foreach ($cleaned AS $key => $value)
{
if (!empty($this->_changes["$key"]))
{
$update[] = "$key = $value";
}
}

if (sizeof($update) > 0)
{
$sql = 'UPDATE ' . $this->_config['tablename'] . '
SET ' . implode(', ', $update) . '
WHERE crc32sid = ' . sprintf('%u', crc32($this->_dbsessionhash)) . '
AND sessionhash = '' . $this->_dbsessionhash . ''';
//echo $sql;
$this->_mysqli->query($sql);
}
}
}

public function getOnlineUserNum()
{
$sql = '
SELECT count(*) as cnt
FROM ' . $this->_config['tablename'] . '
WHERE loggedin = 1
AND heartbeat > '' . date('Y-m-d H:i:s' ,TIMENOW - $this->_config['cookie_timeout']) . ''';

$result = $this->_mysqli->query($sql);
$row = $result->fetch_array(MYSQLI_ASSOC);
return $row['cnt'];
}

private function _gc()
{
$rand_num = rand(); # randow integer between 0 and getrandmax()
if ($rand_num < 100)
{
$sql = 'DELETE FROM ' . $this->_config['tablename'] . '
WHERE heartbeat < '' . date('Y-m-d H:i:s' ,TIMENOW - $this->_config['cookie_timeout']) . ''';

$this->_mysqli->query($sql);
}
}

public function __destruct()
{
$this->_save();
$this->_gc();
$this->_mysqli->close();
}

}

关于"如何实现PHP独立Session数据库存储操作类"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

篇文章 数据 数据库 存储 独立 更多 不错 实用 代码 内容 文章 知识 参考 帮助 有关 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 数据库设计页面的横轴坐标 常熟提供网络技术费用 公司申请网络安全资质 服务器自带的管理端口 金融网络安全不可忽视 数据库及应用有什么推荐的网课 网络服务器配置与管理题目 级联删除和级联更新数据库 地球村网络技术有限公司 香肠派对服务器问题怎么解除 天堂w哪个服务器最火 如何限制服务器的带宽使用 大专学校计算机网络技术暑期实习 祥云杯网络安全大赛需要钱吗 全外显子测序数据库 u1服务器 安全法与网络安全法的课后感 宁波云软件开发工程师 浙江信息化软件开发服务有哪些 计算机网络技术C语言编程码 上海好服务器厂家直销价格 计算机和网络技术三个特点 浙江软件开发过程标准 城厢梅子网络技术 ktv收银服务器后面有个u盘 广州市唐软软件开发 怎样连接系统的前台和后台数据库 杭州安卡网络技术公司怎么样 java请求服务器挂代理 写网页做平台需要服务器吗
0