将 CodeIgniter 2.2 会话与对象一起使用时出现 Unserialize() 偏移错误
Unserialize() offset error when using CodeIgniter 2.2 Sessions with Objects
我正在尝试调试 CodeIgniter 2.2 中的一些旧代码。当 运行 一些数据通过 Session 时,我注意到一个反序列化错误,消息:unserialize(): Error at offset 160 of 163 bytes. 经过一些调试和研究,我发现从会话中反序列化数据时,这是一个常见的反斜杠问题。
我正在使用的序列化数据中包含带有反斜杠的数据对象,这会导致错误发生。我需要一个可以处理标准 class 对象的替代品。
有人可以推荐一个快速替换 codeigniter 的 Session _serialize() 和 _unserialize() 方法的方法吗?
public function data_test() {
$input = array(
(object)array('name' => 'test2', 'desc' => 'bla bla ob/gyn'),
(object)array('name' => 'test2', 'desc' => 'bla bla ob\gyn'),
);
var_dump($input);
$data = $this->_serialize($input);
var_dump($data);
$result = $this->_unserialize($data);
var_dump($result);
}
// --------------------------------------------------------------------
/**
* Serialize an array
*
* This function first converts any slashes found in the array to a temporary
* marker, so when it gets unserialized the slashes will be preserved
*
* @access private
* @param array
* @return string
*/
function _serialize($data) {
if (is_array($data)) {
foreach ($data as $key => $val) {
if (is_string($val)) {
$data[$key] = str_replace('\', '{{slash}}', $val);
}
}
} else {
if (is_string($data)) {
$data = str_replace('\', '{{slash}}', $data);
}
}
return serialize($data);
}
// --------------------------------------------------------------------
/**
* Unserialize
*
* This function unserializes a data string, then converts any
* temporary slash markers back to actual slashes
*
* @access private
* @param array
* @return string
*/
function _unserialize($data) {
$data = unserialize(strip_slashes($data));
if (is_array($data)) {
foreach ($data as $key => $val) {
if (is_string($val)) {
$data[$key] = str_replace('{{slash}}', '\', $val);
}
}
return $data;
}
return (is_string($data)) ? str_replace('{{slash}}', '\', $data) : $data;
}
/**
* Serialize an array
*
* This function serializes the data and then base64_encodes it for
* storage with memcached. This avoids the common backslash issue.
*
* @access private
* @param array
* @return string
*/
function _serialize($data) {
return base64_encode(serialize($data));
}
// --------------------------------------------------------------------
/**
* Unserialize
*
* This function unserializes a data string. I first base64_decodes
* the data from memcached storage.
*/
function _unserialize($data) {
return unserialize(base64_decode($data));
}
如果您使用不同版本的 PHP,或者如果您在会话打开时更改您正在使用的 PHP 版本,有时会遇到此问题。
例如,如果您有一个使用 PHP 5.6.* 的应用程序的会话 cookie,然后您尝试将它与使用 PHP 7.2.*,那么你会得到一个警告错误。或者,如果您有一个打开的会话,然后您更改了与您的应用程序一起使用的 PHP 版本(假设您正在本地开发并切换 PHP 版本),那么您将得到警告。所以最好使用 serialize/unserialize 和 PHP 不变的版本。
我正在尝试调试 CodeIgniter 2.2 中的一些旧代码。当 运行 一些数据通过 Session 时,我注意到一个反序列化错误,消息:unserialize(): Error at offset 160 of 163 bytes. 经过一些调试和研究,我发现从会话中反序列化数据时,这是一个常见的反斜杠问题。
我正在使用的序列化数据中包含带有反斜杠的数据对象,这会导致错误发生。我需要一个可以处理标准 class 对象的替代品。
有人可以推荐一个快速替换 codeigniter 的 Session _serialize() 和 _unserialize() 方法的方法吗?
public function data_test() {
$input = array(
(object)array('name' => 'test2', 'desc' => 'bla bla ob/gyn'),
(object)array('name' => 'test2', 'desc' => 'bla bla ob\gyn'),
);
var_dump($input);
$data = $this->_serialize($input);
var_dump($data);
$result = $this->_unserialize($data);
var_dump($result);
}
// --------------------------------------------------------------------
/**
* Serialize an array
*
* This function first converts any slashes found in the array to a temporary
* marker, so when it gets unserialized the slashes will be preserved
*
* @access private
* @param array
* @return string
*/
function _serialize($data) {
if (is_array($data)) {
foreach ($data as $key => $val) {
if (is_string($val)) {
$data[$key] = str_replace('\', '{{slash}}', $val);
}
}
} else {
if (is_string($data)) {
$data = str_replace('\', '{{slash}}', $data);
}
}
return serialize($data);
}
// --------------------------------------------------------------------
/**
* Unserialize
*
* This function unserializes a data string, then converts any
* temporary slash markers back to actual slashes
*
* @access private
* @param array
* @return string
*/
function _unserialize($data) {
$data = unserialize(strip_slashes($data));
if (is_array($data)) {
foreach ($data as $key => $val) {
if (is_string($val)) {
$data[$key] = str_replace('{{slash}}', '\', $val);
}
}
return $data;
}
return (is_string($data)) ? str_replace('{{slash}}', '\', $data) : $data;
}
/**
* Serialize an array
*
* This function serializes the data and then base64_encodes it for
* storage with memcached. This avoids the common backslash issue.
*
* @access private
* @param array
* @return string
*/
function _serialize($data) {
return base64_encode(serialize($data));
}
// --------------------------------------------------------------------
/**
* Unserialize
*
* This function unserializes a data string. I first base64_decodes
* the data from memcached storage.
*/
function _unserialize($data) {
return unserialize(base64_decode($data));
}
如果您使用不同版本的 PHP,或者如果您在会话打开时更改您正在使用的 PHP 版本,有时会遇到此问题。
例如,如果您有一个使用 PHP 5.6.* 的应用程序的会话 cookie,然后您尝试将它与使用 PHP 7.2.*,那么你会得到一个警告错误。或者,如果您有一个打开的会话,然后您更改了与您的应用程序一起使用的 PHP 版本(假设您正在本地开发并切换 PHP 版本),那么您将得到警告。所以最好使用 serialize/unserialize 和 PHP 不变的版本。