我刚刚从PHP 7.0迁移到PHP 7.1(当前版本的WAMP的全新/干净安装)并且它似乎已经破坏了自定义会话处理程序中的某些东西,它应该将会话保存到数据库而不是使用文件系统.
自定义处理程序类是:
class db_session_handler实现SessionHandlerInterface {
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
}?>
它由以下内容初始化:ini_set('session.use_only_cookies',1);
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!!!!');
}
Run Code Online (Sandbox Code Playgroud)
通过session_set_save_handler()的手册页阅读我无法发现任何可能解释我得到的错误的内容:
警告:在session_start():无法读取会话数据:在C的用户(/瓦帕/ TMP路径::C):\瓦帕\ WWW\universal_empires \库\在线路36上bootstrap.php中
该文件中的第36行是对session_start()的调用.
围绕我能找到的唯一修复的Gooogling特定于给定的框架.我需要知道的是导致session_start()失败的原因(从读取有关7.1 session_start()的更改返回false而不是在某些事情不正确时尝试进行操作.
我的猜测是7.1中的某些内容发生了变化,其中7.0可能允许继续进行,但在7.1中它更严格,无论问题是什么,并使session_start()返回false.
我已经清空了数据库中的会话表,并检查了存储基于文件的会话的位置.唯一存在的"基于文件"的会话文件是PHPMyAdmin.
有谁知道它在PHP 7.1中的犯规是什么,它不会在PHP 7.0中犯规?
已找到罪魁祸首.事实证明,如果没有会话存在,session_start()不喜欢自定义会话处理程序的read方法返回false.如果其他人遇到类似的问题,如果你没有会话,那么read方法需要返回一个空字符串而不是false或null.
该解决方案被发现在http://php.net/manual/en/function.session-start.php#120589)我一直在寻找了一下session_set_save_handler(该手册页,没想到的解决方案实际上是在评论部分session_start()页面.
我不知道为什么对session_start()方法期望从自定义会话处理程序的read方法获取的内容进行了更改
| 归档时间: |
|
| 查看次数: |
4413 次 |
| 最近记录: |