Php unserialize()[function.unserialize]:在49151字节的偏移量49151处出错
我和网站上的许多人一样,在将对象存储到数据库中并检索后,出现了偏移错误。如果我不储存,一切正常:Php unserialize()[function.unserialize]:在49151字节的偏移量49151处出错,php,Php,我和网站上的许多人一样,在将对象存储到数据库中并检索后,出现了偏移错误。如果我不储存,一切正常: $serializedObject = serialize($this); $unSerializedObject = unserialize($serializedObject); 此外,我在保存数据和从数据库检索数据时使用base64编码,但这并没有帮助。不过,我不会逃跑。 我的对象处理一些字符串。我发现用这个字符串: A woman is travelling around the worl
$serializedObject = serialize($this);
$unSerializedObject = unserialize($serializedObject);
此外,我在保存数据和从数据库检索数据时使用base64编码,但这并没有帮助。不过,我不会逃跑。
我的对象处理一些字符串。我发现用这个字符串:
A woman is travelling around the world. She is 28 years old and she is from Great Britain.
She cannot use a car or a plane on her
它很好用。但是,当我再添加一个空格和单词[Travel]时,就会出现错误。以下是包含一个单词的字符串:
A woman is travelling around the world. She is 28 years old and she is from Great Britain.
She cannot use a car or a plane on her journey
我的问题是为什么会出现错误
serialize($this)
的输出是否针对没有单词的文本运行
serialize($this)
的输出是否针对带有单词旅程的文本运行
更新
我将对象保存到的表具有字符集utf-8
,并且该列没有定义字符集,因为它是BLOB类型。
mb\u detect\u编码(序列化($this))
返回UTF-8
$sql
没有转义。这是在我使用的Kohana框架内执行查询的方式:
$result = mysql_query($sql, $this->_connection)
原始答复:
MySQL中的一个文本字段最多存储65535字节,所以我猜它在那里被截断了
改用中文本或长文本
除此之外,还存在如何将数据输入和输出数据库的潜在问题。PHP序列化字符串可以包含空字节(字节0),这似乎是无法正确传输的
解决这个问题的一种方法是通过类似base64\u encode()
的东西对字符串进行编码,它使用非常友好的字母数字/符号字母表。如果您将BLOB
类型增加到MEDIUMBLOB
或LONGBLOB
,这将解决您的问题
但是,如果正确地将查询发送到数据库,则可以安全地发送原始字符串。因为您使用的是Kohana,所以这里有一个对我来说非常好的示例
简短版本:
$sql = 'INSERT INTO serialized_object (data) VALUES (:data)';
DB::query(Database::INSERT, $sql)->
param(':data', $serialization)->
execute();
代码:
此方法解决了问题:
$toDatabse = base64_encode(serialize($data)); // Save to database
$fromDatabase = unserialize(base64_decode($data)); //Getting Save Format
但问题仍然是,发现错误的根本原因是什么?谢谢您的回答,但在我将对象存储到数据库之前检测到的问题。如果你说的是字段类型,我在数据库中使用的是BLOB字段。仅供参考:TINYTEXT
存储254字节,TEXT
存储64KiB减去2字节,MEDIUMTEXT
存储16 MiB减去3字节,LONGTEXT
存储4 GiB减去4字节。BLOB具有相同的存储大小。可能在保存到数据库时没有正确转义数据。我看不到任何证据表明您的非序列化在使用数据库之外失败。此函数仅检查简单的可变长度,它不能很好地处理对象的私有/公共属性。@dev null allender,那么您的意思是,如果我的对象具有私有属性,它将显示不正确的数据?@Maximus,您提到您正在使用Kohana。您是否通过扩展Kohana_ORM记录的对象保存它?另外,您能否粘贴echo serialize($this)
和echo bin2hex(serialize($this))的内容
。(如果它真的很大的话,可以通过某种方式。)@Matthew,不,我是手动操作的DB::query(Database::INSERT,$sql)->execute()代码>。粘贴的序列化对象。@Maximus,是的,UTF8字符存储在blob/text中时可能需要2个或更多字节。(对于大小以字符为单位的CHAR/VARCHAR,情况并非如此。它仍然会消耗这些额外的字节,但这已计入VARCHAR的长度中。)这意味着您没有正确地将数据保存到数据库中base64_encode
仅使用“安全”字符,这可能是为了解决您进入数据库时出现的错误编码。@Matthew,那么我如何找出问题所在?请用两件事更新您的问题:如何连接到数据库(密码/用户名不相关)以及如何发送查询。我猜要么是字符集错了,要么是你没有转义数据(例如,mysql\u real\u escape\u string
)。@Matthew,我用有关字符集的信息更新了我的问题。我使用的是Kohana框架,所以我需要一些时间来弄清楚它是如何连接到数据库并发送查询的。你说得对,我不是在逃避数据,我应该在哪里做?
<?php
return array
(
'default' => array(
'type' => 'PDO',
'connection' => array(
/**
* The following options are available for PDO:
*
* string dsn Data Source Name
* string username database username
* string password database password
* boolean persistent use persistent connections?
*/
'dsn' => 'mysql:host=127.0.0.1;dbname=test',
'username' => 'root',
'password' => '****',
'persistent' => FALSE,
),
/**
* The following extra options are available for PDO:
*
* string identifier set the escaping identifier
*/
'table_prefix' => '',
'charset' => 'utf8',
'caching' => FALSE,
),
);
CREATE TABLE `serialized_object` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`data` longblob NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
$toDatabse = base64_encode(serialize($data)); // Save to database
$fromDatabase = unserialize(base64_decode($data)); //Getting Save Format