PHP:自定义会话处理程序反序列化无法在 Windows 上运行
PHP: Custom Session Handler Unserialize Not Working on Windows
我的应用程序的开发环境是 Zend Framework 1.11、MSSQL Server 2012、SQLSRV Extension for Database connectivity with PDO、Windows 7、IIS 7。使用自定义会话处理程序将会话存储在数据库中 class.
问题是当我在 Bootstrap.php 文件中写入的 session_start() 之后打印 $_SESSION 时,它没有显示完整的未序列化的会话数据数组。似乎由会话 class 处理程序的 "read" 方法返回的会话数据,由于某种原因没有被反序列化。这是我的源代码:-
Bootstrap.php
protected function _initSession() {
$handler = new Mcd_Core_SessionHandler_Database();
session_set_save_handler(
array($handler, 'open'),
array($handler, 'close'),
array($handler, 'read'),
array($handler, 'write'),
array($handler, 'destroy'),
array($handler, 'gc')
);
session_start();
echo "<pre>";
print_r($_SESSION);
}
会话处理器Class
<?php
class My_Core_SessionHandler_Database
{
protected $dbh;
protected $ipAddress = '';
public function __construct() {
$this->dbh = My_Core_Config::get_dbinstance();
}
public function open($savePath, $sessionId) {
return true;
}
public function close() {
return true;
}
public function read($sessionId) {
$query = "SELECT TOP 1 CAST(session as varchar(max)) as session
FROM t_php_session
WHERE php_session_id = '".$sessionId."'
AND DATEADD(minute, ".My_Core_Config::get_value('session_timeout_period').", created) >= GETDATE()
AND user_ip = '".$this->ipAddress."'";
$stmt = $this->dbh->prepare($query);
$stmt->execute();
$result = $stmt->fetchColumn();
if ($result === false) {
return '';
}
return $result;
}
public function write($sessionId, $sessionData) {
$query = "
SELECT id
FROM t_php_session
WHERE php_session_id = ?
";
$stmt = $this->dbh->prepare($query);
$stmt->execute(array($sessionId));
$result = $stmt->fetchColumn();
if (empty($result)) {
$query = "INSERT INTO t_php_session (php_session_id, session, user_ip, created) VALUES (?, CONVERT(VARBINARY(max), ?), ".$this->ipAddress.", GETDATE())";
$stmt = $this->dbh->prepare($query);
$stmt->execute(array($sessionId, $sessionData));
} else {
$query = "
UPDATE t_php_session
SET session = CONVERT(VARBINARY(max), ?),
user_ip = ".$this->ipAddress.",
created = GETDATE()
WHERE id = ?
";
$stmt = $this->dbh->prepare($query);
$stmt->execute(array($sessionData, $result));
}
return true;
}
public function destroy($sessionId) {
$query = 'DELETE FROM t_php_session WHERE php_session_id = ?';
$stmt = $this->dbh->prepare($query);
$stmt->execute(array($sessionId));
return true;
}
public function gc($maxlifetime) {
$query = "
DELETE FROM t_php_session
WHERE DATEADD(minute, ".My_Core_Config::get_value('session_timeout_period').", created) < GETDATE()";
$stmt = $this->dbh->prepare($query);
$stmt->execute();
return true;
}
}
数据库table中session字段的数据类型是varbinary(max)。我只是想这可能是问题所在,但不确定。
会话处理程序 class 的 read 方法的输出是:
My_Core_Session|a:1:{s:16:"My_Core_Session";a:4:{s:19:"previous_controller";N;s:15:"previous_action";N;s:18:"current_controller";s:16:"authentification";s:14:"current_action";s:5:"login";}}
Bootstrap.php 中 $_SESSION 的输出是:
Array
(
[My_Core_Session] =>
)
输出应该在哪里:
Array
(
[My_Core_Session] => Array
(
[My_Core_Session] => Array
(
[previous_controller] =>
[previous_action] =>
[current_controller] => authentification
[current_action] => login
)
)
)
此应用程序在 Linux 上作为同一个数据库运行良好,正在使用源代码,但在 Apache 2.2、FreeTDS、Dblib 等不同环境中。我们刚刚将此应用程序从 Linux 移至 Windows 并面临此问题。
我找到了解决方案,并想与可能面临同样问题的人分享。问题是 PHP 引擎无法 deserialize
从 MSSQL Server 数据库中获取的会话数据可能是一些垃圾随数据一起出现。字段(保存会话的位置)的数据类型为 varbinary (max)
。我只是将其更改为 varchar (max)
以查看它是否有效并且有效:)
这是一个特定的用例,其中在带有 MSSQL Server 数据库的 zend 框架中使用了自定义会话处理程序。幸运的是,现在已经解决了:)
祝你好运!!
我的应用程序的开发环境是 Zend Framework 1.11、MSSQL Server 2012、SQLSRV Extension for Database connectivity with PDO、Windows 7、IIS 7。使用自定义会话处理程序将会话存储在数据库中 class.
问题是当我在 Bootstrap.php 文件中写入的 session_start() 之后打印 $_SESSION 时,它没有显示完整的未序列化的会话数据数组。似乎由会话 class 处理程序的 "read" 方法返回的会话数据,由于某种原因没有被反序列化。这是我的源代码:-
Bootstrap.php
protected function _initSession() {
$handler = new Mcd_Core_SessionHandler_Database();
session_set_save_handler(
array($handler, 'open'),
array($handler, 'close'),
array($handler, 'read'),
array($handler, 'write'),
array($handler, 'destroy'),
array($handler, 'gc')
);
session_start();
echo "<pre>";
print_r($_SESSION);
}
会话处理器Class
<?php
class My_Core_SessionHandler_Database
{
protected $dbh;
protected $ipAddress = '';
public function __construct() {
$this->dbh = My_Core_Config::get_dbinstance();
}
public function open($savePath, $sessionId) {
return true;
}
public function close() {
return true;
}
public function read($sessionId) {
$query = "SELECT TOP 1 CAST(session as varchar(max)) as session
FROM t_php_session
WHERE php_session_id = '".$sessionId."'
AND DATEADD(minute, ".My_Core_Config::get_value('session_timeout_period').", created) >= GETDATE()
AND user_ip = '".$this->ipAddress."'";
$stmt = $this->dbh->prepare($query);
$stmt->execute();
$result = $stmt->fetchColumn();
if ($result === false) {
return '';
}
return $result;
}
public function write($sessionId, $sessionData) {
$query = "
SELECT id
FROM t_php_session
WHERE php_session_id = ?
";
$stmt = $this->dbh->prepare($query);
$stmt->execute(array($sessionId));
$result = $stmt->fetchColumn();
if (empty($result)) {
$query = "INSERT INTO t_php_session (php_session_id, session, user_ip, created) VALUES (?, CONVERT(VARBINARY(max), ?), ".$this->ipAddress.", GETDATE())";
$stmt = $this->dbh->prepare($query);
$stmt->execute(array($sessionId, $sessionData));
} else {
$query = "
UPDATE t_php_session
SET session = CONVERT(VARBINARY(max), ?),
user_ip = ".$this->ipAddress.",
created = GETDATE()
WHERE id = ?
";
$stmt = $this->dbh->prepare($query);
$stmt->execute(array($sessionData, $result));
}
return true;
}
public function destroy($sessionId) {
$query = 'DELETE FROM t_php_session WHERE php_session_id = ?';
$stmt = $this->dbh->prepare($query);
$stmt->execute(array($sessionId));
return true;
}
public function gc($maxlifetime) {
$query = "
DELETE FROM t_php_session
WHERE DATEADD(minute, ".My_Core_Config::get_value('session_timeout_period').", created) < GETDATE()";
$stmt = $this->dbh->prepare($query);
$stmt->execute();
return true;
}
}
数据库table中session字段的数据类型是varbinary(max)。我只是想这可能是问题所在,但不确定。
会话处理程序 class 的 read 方法的输出是:
My_Core_Session|a:1:{s:16:"My_Core_Session";a:4:{s:19:"previous_controller";N;s:15:"previous_action";N;s:18:"current_controller";s:16:"authentification";s:14:"current_action";s:5:"login";}}
Bootstrap.php 中 $_SESSION 的输出是:
Array
(
[My_Core_Session] =>
)
输出应该在哪里:
Array
(
[My_Core_Session] => Array
(
[My_Core_Session] => Array
(
[previous_controller] =>
[previous_action] =>
[current_controller] => authentification
[current_action] => login
)
)
)
此应用程序在 Linux 上作为同一个数据库运行良好,正在使用源代码,但在 Apache 2.2、FreeTDS、Dblib 等不同环境中。我们刚刚将此应用程序从 Linux 移至 Windows 并面临此问题。
我找到了解决方案,并想与可能面临同样问题的人分享。问题是 PHP 引擎无法 deserialize
从 MSSQL Server 数据库中获取的会话数据可能是一些垃圾随数据一起出现。字段(保存会话的位置)的数据类型为 varbinary (max)
。我只是将其更改为 varchar (max)
以查看它是否有效并且有效:)
这是一个特定的用例,其中在带有 MSSQL Server 数据库的 zend 框架中使用了自定义会话处理程序。幸运的是,现在已经解决了:)
祝你好运!!