我使用以下 lib 来管理会话,将会话值存储在数据库中,一切正常,我可以get
和set
会话值。
但是重新启动后,我无法获取会话值。
当我尝试使用set
会话值时,我会在数据库中创建新行而不是进行更新。
LIB.php
<?php
/**
* @category Security
* @version 1.0
* @author First Last
* */
class mySessionHandler {
private $_db = NULL;
private $_table_name = 'sessions';
private $_cookie_name = 'session_cookie';
private $_seconds_till_expiration = 43200; // 2 hours
private $_renewal_time = 300; // 5 minutes
private $_expire_on_close = FALSE;
private $_ip_address = FALSE;
private $_user_agent = FALSE;
private $_secure_cookie = FALSE;
private $_session_id = FALSE;
private $_data = array();
public function __construct(array $config) {
$this->_setConfig($config);
if ($this->_read()) {
$this->_update();
} else {
$this->_create();
}
$this->_cleanExpired();
$this->_setCookie();
}
public function regenerateId() {
$old_session_id = $this->_session_id;
$this->_session_id = $this->_generateId();
$stmt = $this->_db->prepare("UPDATE {$this->_table_name} SET time_updated = ?, session_id = ? WHERE session_id = ?");
$stmt->execute(array(time(), $this->_session_id, $old_session_id));
$this->_setCookie();
}
public function setData($key, $value) {
$this->_data[$key] = $value;
$this->_write();
}
public function unsetData($key) {
if (isset($this->_data[$key])) {
unset($this->_data[$key]);
}
}
function getData($key) {
return isset($this->_data[$key]) ? $this->_data[$key] : FALSE;
}
public function getAllData() {
return $this->_data;
}
public function destroy() {
if (isset($this->_session_id)) {
$stmt = $this->_db->prepare("DELETE FROM {$this->_table_name} WHERE session_id = ?");
$stmt->execute(array($this->_session_id));
}
setcookie($this->_cookie_name, '', time() - 31500000, NULL, NULL, NULL, NULL);
}
private function _read() {
$session_id = filter_input(INPUT_COOKIE, $this->_cookie_name) ? filter_input(INPUT_COOKIE, $this->_cookie_name) : FALSE;
if (!$session_id) {
return FALSE;
}
$this->_session_id = $session_id;
$stmt = $this->_db->prepare("SELECT data, time_updated, user_agent, ip_address FROM {$this->_table_name} WHERE session_id = ?");
$stmt->execute(array($this->_session_id));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if ($result !== FALSE && count($result) > 0) {
if (!$this->_expire_on_close && (($result['time_updated'] + $this->_seconds_till_expiration) < time())) {
$this->destroy();
return FALSE;
}
if ($this->_ip_address && ($result['ip_address'] != $this->_ip_address)) {
$this->_flagForUpdate();
return FALSE;
}
if ($this->_user_agent && ($result['user_agent'] != $this->_user_agent)) {
$this->_flagForUpdate();
return FALSE;
}
$this->_checkUpdateFlag();
$this->_checkIdRenewal();
$user_data = unserialize($result['data']);
if ($user_data) {
$this->_data = $user_data;
unset($user_data);
}return TRUE;
}return FALSE;
}
private function _create() {
$this->_session_id = $this->_generateId();
$stmt = $this->_db->prepare("INSERT INTO {$this->_table_name} (session_id, user_agent, ip_address, time_updated) VALUES (?, ?, ?, ?)");
$stmt->execute(array($this->_session_id, $this->_user_agent, $this->_ip_address, time()));
}
private function _update() {
$stmt = $this->_db->prepare("UPDATE {$this->_table_name} SET time_updated = ? WHERE session_id = ?");
$stmt->execute(array(time(), $this->_session_id));
}
private function _write() {
if (count($this->_data) == 0) {
$custom_data = '';
} else {
$custom_data = serialize($this->_data);
}
$stmt = $this->_db->prepare("UPDATE {$this->_table_name} SET data = ?, time_updated = ? WHERE session_id = ?");
$stmt->execute(array($custom_data, time(), $this->_session_id));
}
private function _setCookie() {
setcookie(
$this->_cookie_name, $this->_session_id, ($this->_expire_on_close) ? 0 : time() + $this->_seconds_till_expiration, // Expiration timestamp
NULL, NULL, $this->_secure_cookie, // Will cookie be set without HTTPS?
TRUE // HttpOnly
);
}
private function _cleanExpired() {
if (mt_rand(1, 1000) == 1) {
$stmt = $this->_db->prepare("DELETE FROM {$this->_table_name} WHERE (time_updated + {$this->_seconds_till_expiration}) < ?");
$stmt->execute(array(time()));
}
}
function _generateId() {
$salt = 'x7^!bo3p,.$$!$6[&Q.#,//@i"%[X';
$random_number = '9085723012206';
$random_txt = 'sanoj';
$ip_address_fragment = md5(substr(filter_input(INPUT_SERVER, 'REMOTE_ADDR'), 0, 5));
$hash_data = $random_number . $ip_address_fragment . $random_txt . $salt;
$hash = hash('sha256', $hash_data);
return $hash;
}
private function _checkIdRenewal() {
$stmt = $this->_db->prepare("SELECT time_updated FROM {$this->_table_name} WHERE session_id = ?");
$stmt->execute(array($this->_session_id));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if ($result !== FALSE && count($result) > 0) {
if ((time() - $this->_renewal_time) > $result['time_updated']) {
$this->regenerateId();
}
}
}
private function _flagForUpdate() {
$stmt = $this->_db->prepare("UPDATE {$this->_table_name} SET flagged_for_update = '1' WHERE session_id = ?");
$stmt->execute(array($this->_session_id));
}
private function _checkUpdateFlag() {
$stmt = $this->_db->prepare("SELECT flagged_for_update FROM {$this->_table_name} WHERE session_id = ?");
$stmt->execute(array($this->_session_id));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if ($result !== FALSE && count($result) > 0) {
if ($result['flagged_for_update']) {
$this->regenerateId();
$stmt = $this->_db->prepare("UPDATE {$this->_table_name} SET flagged_for_update = '0' WHERE session_id = ?");
$stmt->execute(array($this->_session_id));
}
}
}
private function _setConfig(array $config) {
if (isset($config['database'])) {
$this->_db = $config['database'];
} else {
throw new Exception('Database handle not set!');
}
if (isset($config['cookie_name'])) {
if (!ctype_alnum(str_replace(array('-', '_'), '', $config['cookie_name']))) {
throw new Exception('Invalid cookie name!');
} $this->_cookie_name = $config['cookie_name'];
}
if (isset($config['table_name'])) {
if (!ctype_alnum(str_replace(array('-', '_'), '', $config['table_name']))) {
throw new Exception('Invalid table name!');
} $this->_table_name = $config['table_name'];
}
if (isset($config['seconds_till_expiration'])) {
if (!is_int($config['seconds_till_expiration']) || !preg_match('#[0-9]#', $config['seconds_till_expiration'])) {
throw new Exception('Seconds till expiration must be a valid number.');
}
if ($config['seconds_till_expiration'] < 1) {
throw new Exception('Seconds till expiration can not be zero or less. Enable session expiration when the browser closes instead.');
}
$this->_seconds_till_expiration = (int) $config['seconds_till_expiration'];
}
if (isset($config['expire_on_close'])) {
if (!is_bool($config['expire_on_close'])) {
throw new Exception('Expire on close must be either TRUE or FALSE.');
}
$this->_expire_on_close = $config['expire_on_close'];
}
if (isset($config['renewal_time'])) {
if (!is_int($config['renewal_time']) || !preg_match('#[0-9]#', $config['renewal_time'])) {
throw new Exception('Session renewal time must be a valid number.');
}
if ($config['renewal_time'] < 1) {
throw new Exception('Session renewal time can not be zero or less.');
}
$this->_renewal_time = (int) $config['renewal_time'];
}
if (isset($config['check_ip_address'])) {
if (!is_string($config['check_ip_address'])) {
throw new Exception('The IP address must be a string similar to this: \'172.16.254.1\'.');
}
if (!preg_match('/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/', $config['check_ip_address'])) {
throw new Exception('Invalid IP address.');
}
$this->_ip_address = $config['check_ip_address'];
}
if (isset($config['check_user_agent'])) {
$this->_user_agent = substr($config['check_user_agent'], 0, 999);
} if (isset($config['secure_cookie'])) {
if (!is_bool($config['secure_cookie'])) {
throw new Exception('The secure cookie option must be either TRUE or FALSE.');
}
$this->_secure_cookie = $config['secure_cookie'];
}
}
}
即使重新启动浏览器后,如何获取会话值,
GET.PHP
ob_start();
session_start();
include_once('index.php');
echo $session->getData('fname').'<br>';
echo $session->getData('password').'<br>';
echo $session->getData('email').'<br>';
SET.PHP
ob_start();
session_start();
include_once('index.php');
$session->setData('fname', 'first last');
$session->setData('password', '123456');
$session->setData('email', 'first@last.com');
$sesi = $session->_generateId();
echo $sesi;
$_SESSION['test'] = $sesi;
答案 0 :(得分:1)
尝试替换_setCookie()
,以使您的cookie不会过期
private function _setCookie() {
setcookie($this->_cookie_name, $this->_session_id, ($this->_expire_on_close) ? 0 : time() + (10 * 365 * 24 * 60 * 60), //Expiration timestamp
NULL, NULL, $this->_secure_cookie, // Will cookie be set without HTTPS?
TRUE // HttpOnly
);
}