Unserialize () [function.unserialize]: Error at offset 49151 of 49151 bytes

I have an offset error, like many on a website, after storing an object in a database and retrieving it. If I do not store it, everything works fine:

$serializedObject = serialize($this); $unSerializedObject = unserialize($serializedObject); 

In addition, I use base64 encoding when saving data and retrieving it from the database, but this does not help. However, I am not running away. My object is processing some string. I found that with this line:

 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 

It works great. But when I add another space and the word [travel], an error appears. Here is a line with this one word:

 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 

Question: why does the error occur?

Here is the output of the serialize($this) run against text without the word journey

Here is the output of the serialize($this) run against the text with the word journey

UPDATE

In the table in which I save the object, there is a charset utf-8 and a column without encoding, defined with its type BLOB. mb_detect_encoding(serialize($this)) returns utf-8

There is no escaping for $sql . This is how the query within Kohana that I use is executed:

 $result = mysql_query($sql, $this->_connection) 
+3
php
Oct 19 '13 at 17:43 on
source share
2 answers

Original answer:

The TEXT field in MySQL stores up to 65535 bytes, so I assume it is truncated there.

Use MEDIUMTEXT or LONGTEXT instead.

In addition to this, there are potential problems with how you get data into and out of the database. PHP serialized strings can contain null bytes (byte 0), and it looks like it is not being transmitted properly.

One way around this is to encode the string through something like base64_encode() , which uses a very convenient alphanumeric alphabet / character. This will solve your problems if you increase the BLOB type to MEDIUMBLOB or LONGBLOB .

However, if you send your queries correctly to the database, you can safely send the original string. Since you are using Kohana, here is a sample that works great for me.

Short version:

 $sql = 'INSERT INTO serialized_object (data) VALUES (:data)'; DB::query(Database::INSERT, $sql)-> param(':data', $serialization)-> execute(); 

the code:

 <?php class Article {} class Word {} class Controller_Welcome extends Controller { public function action_index() { $object = unserialize(hex2bin(file_get_contents('/tmp/data.hex'))); $serialization = serialize($object); $sql = 'INSERT INTO serialized_object (data) VALUES (:data)'; DB::query(Database::INSERT, $sql)-> param(':data', $serialization)-> execute(); $saved_length = DB::query(Database::SELECT, ' SELECT LENGTH(data) AS l FROM serialized_object ORDER BY id DESC LIMIT 1 ')->execute()->get('l'); if ($saved_length != strlen($serialization)) { throw new Exception("Database length is incorrect. Value is corrupted in database."); } $saved_serialization = DB::query(Database::SELECT, ' SELECT data FROM serialized_object ORDER BY id DESC LIMIT 1 ')->execute()->get('data'); $saved_object = unserialize($saved_serialization); if (!$saved_object) { throw new Exception("Unable to unserialize object."); } if ($saved_object != $object) { throw new Exception("Saved object is not equal to object."); } $this->response->body('Everything is fine.'); } } 

database.php:

 <?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, ), ); 

Scheme:

 CREATE TABLE `serialized_object` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `data` longblob NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 
+7
Oct 19 '13 at 18:05
source share

The issue is resolved using this approach:

 $toDatabse = base64_encode(serialize($data)); // Save to database $fromDatabase = unserialize(base64_decode($data)); //Getting Save Format 

But the question remains, what are the main causes of errors detected by Baba by the findSerializeError function ?

+2
Oct 19 '13 at 18:10
source share



All Articles