【发布时间】:2019-10-26 03:07:16
【问题描述】:
我刚刚在计算机上从 PHP 7.0 迁移到 PHP 7.1(全新/全新安装当前版本的 WAMP),它似乎破坏了自定义会话处理程序中的某些内容,该处理程序应该将会话保存到数据库而不是使用文件系统。
自定义hander类是:
class db_session_handler implements SessionHandlerInterface {
public function __construct($db) {
$this->db = $db;
}
public function open($save_path,$session_name) {
$this->db;
return true;
}
public function close() {
unset($this->db);
return true;
}
public function read($session_id) {
if (!isset($session_id)) {
$session_id='';
}
try {
$sql="
SELECT
sess_data
FROM
ue_user_session
WHERE
sess_id = :sess_id
";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':sess_id', $session_id);
$stmt->execute();
$res = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (count($res) <> 1 ) {
return false;
} else {
return $res[0]['sess_data'];
}
}
catch (PDOException $e) {
error_log('Error reading the session data table in the session reading method.',3,"C:\wamp\www\universal_empires\test_log.txt");
error_log(" Query with error: $sql",3,"C:\wamp\www\universal_empires\test_log.txt");
error_log(" Reason given: $e->getMessage()",3,"C:\wamp\www\universal_empires\test_log.txt");
return false;
}
}
public function write($session_id,$session_data) {
try {
$sql="
SELECT
sess_data
FROM
ue_user_session
WHERE
sess_id = :sess_id
";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':sess_id', $session_id);
$stmt->execute();
$res = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
catch (PDOException $e) {
error_log('Error reading the session data table in the session reading method.',3,"C:\wamp\www\universal_empires\test_log.txt");
error_log(" Query with error: $sql",3,"C:\wamp\www\universal_empires\test_log.txt");
error_log(" Reason given: $e->getMessage()",3,"C:\wamp\www\universal_empires\test_log.txt");
return false;
}
$ip = get_ip();
if (isset($_SESSION['user_id'])) {
$user_id = (int) $_SESSION['user_id'];
} else {
$user_id= (int) 0;
}
if (empty($res)) {
if (!isset($_SERVER['REDIRECT_URL'])) {
$location = 'Unknown';
} else {
$location = $_SERVER['REDIRECT_URL'];
}
try {
if (count($res) === 0) {
$sql="
INSERT INTO
ue_user_session
(
sess_id
, user
, start
, last_activity
, location
, ip
, user_agent
, user_host
, user_language
, expires
, sess_data
)
VALUES
(
:sess_id
, 0
, NOW()
, NOW()
, :location
, :ip
, :user_agent
, :user_host
, :user_lang
, DATE_ADD(NOW(), INTERVAL 30 MINUTE)
, :sess_data
)
";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':sess_id', $session_id);
$stmt->bindParam(':location', $location);
$stmt->bindParam(':ip', $ip);
$stmt->bindParam(':user_agent', $_SERVER['HTTP_USER_AGENT']);
$stmt->bindParam(':user_host', $_SERVER['REMOTE_HOST']);
$stmt->bindParam(':user_lang', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
$stmt->bindParam(':sess_data', $session_data);
$stmt->execute();
return true;
}
}
catch (PDOException $e) {
error_log('Error reading the session data table in the session reading method.',3,"C:\wamp\www\universal_empires\test_log.txt");
error_log(" Query with error: $sql",3,"C:\wamp\www\universal_empires\test_log.txt");
error_log(" Reason given: $e->getMessage()",3,"C:\wamp\www\universal_empires\test_log.txt");
return false;
}
} else {
try {
$sql="
UPDATE
ue_user
SET
last_activity = NOW()
WHERE
id = :user_id
";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':user_id', $user_id);
$stmt->execute();
}
catch (PDOException $e) {
error_log('Error reading the session data table in the session reading method.',3,"C:\wamp\www\universal_empires\test_log.txt");
error_log(" Query with error: $sql",3,"C:\wamp\www\universal_empires\test_log.txt");
error_log(" Reason given: $e->getMessage()",3,"C:\wamp\www\universal_empires\test_log.txt");
return false;
}
if (!isset($_SERVER['REDIRECT_URL'])) {
$location = 'Unknown';
} else {
$location = $_SERVER['REDIRECT_URL'];
}
try {
$sql="
UPDATE
ue_user_session
SET
last_activity = NOW()
, expires = DATE_ADD(NOW(), INTERVAL 30 MINUTE)
, location = :location
, ip = :ip
, user_agent = :user_agent
, user_host = :user_host
, user_language = :user_lang
, sess_data = :sess_data
, user = :user_id
WHERE
sess_id = :sess_id
";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':location', $location);
$stmt->bindParam(':ip', $ip);
$stmt->bindParam(':user_agent', $_SERVER['HTTP_USER_AGENT']);
$stmt->bindParam(':user_host', $_SERVER['REMOTE_HOST']);
$stmt->bindParam(':user_lang', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
$stmt->bindParam(':sess_data', $session_data);
$stmt->bindParam(':user_id', $user_id);
$stmt->bindParam(':sess_id', $session_id);
$stmt->execute();
return true;
}
catch (PDOException $e) {
error_log('Error reading the session data table in the session reading method.',3,"C:\wamp\www\universal_empires\test_log.txt");
error_log(" Query with error: $sql",3,"C:\wamp\www\universal_empires\test_log.txt");
error_log(" Reason given: $e->getMessage()",3,"C:\wamp\www\universal_empires\test_log.txt");
return false;
}
}
$this->gc();
}
public function destroy($session_id) {
try {
$sql="
DELETE FROM
ue_user_session
WHERE
sess_id = :sess_id
";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':sess_id', $session_id);
$stmt->execute();
return true;
}
catch (PDOException $e) {
error_log('Error reading the session data table in the session reading method.',3,"C:\wamp\www\universal_empires\test_log.txt");
error_log(" Query with error: $sql",3,"C:\wamp\www\universal_empires\test_log.txt");
error_log(" Reason given: $e->getMessage()",3,"C:\wamp\www\universal_empires\test_log.txt");
return false;
}
}
public function gc($max_lifetime) {
try {
$sql="
DELETE FROM
ue_user_session
WHERE
NOW() > expires
";
$stmt = $this->db->prepare($sql);
$stmt->execute();
return true;
}
catch (PDOException $e) {
error_log('Error reading the session data table in the session reading method.',3,"C:\wamp\www\universal_empires\test_log.txt");
error_log(" Query with error: $sql",3,"C:\wamp\www\universal_empires\test_log.txt");
error_log(" Reason given: $e->getMessage()",3,"C:\wamp\www\universal_empires\test_log.txt");
return false;
}
}
}
它的发起者:
ini_set('session.use_only_cookies', 1);
$db_session_handler = new db_session_handler($db);
session_set_save_handler($db_session_handler, true);
if (session_start() === false ) {
die('The Session Handler Is Broken!!!!');
}
阅读session_set_save_handler() 的手册页,我找不到任何可以解释我遇到的错误的内容:
警告:session_start():无法读取会话数据:第 36 行 C:\wamp\www\universal_empires\libs\bootstrap.php 中的用户(路径:c:/wamp/tmp)
该文件中的第 36 行是对 session_start() 的调用。
搜索我能找到的唯一修复程序是特定于给定框架的。我需要知道的是导致session_start() 失败的原因(从阅读对7.1 的更改session_start() 返回false,而不是在出现问题时尝试重复。
我的猜测是,在 7.1 中发生了一些变化,在 7.0 中它可能被允许继续,但在 7.1 中,无论出现什么问题,它都更加严格,并且使 session_start() 返回 false。
我已经清空了数据库中的会话表,并检查了基于文件的会话的存储位置。唯一存在的“基于文件”的会话文件是 PHPMyAdmin。
有谁知道它在 PHP 7.1 中犯规而在 PHP 7.0 中没有犯规?
【问题讨论】:
-
第一反应:session_set_save_handler 返回什么——真还是假?升级 PHP 是否更改了您需要的任何 php.ini 值?我正在寻找其他答案。
-
session_set_save_handler 返回真。我不得不重新安装 WAMP,因为旧安装由于某种原因已经崩溃并删除了它的 php.ini 文件