unserialize () : Error en el desplazamiento 49151 de 49151 bytes

Tengo el error de compensación como muchos en el sitio web después de almacenar el objeto en la base de datos y de recuperarlo. Si no lo guardo todo funciona bien:

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

Además, utilizo la encoding base64 al guardar datos y recuperarlos de la base de datos, pero esto no ayuda. Aunque no escapo nada. Mi objeto procesa alguna cadena. Lo que descubrí es que con esta cadena:

 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 

Funciona bien. Pero cuando agrego un espacio y una palabra más [viaje], aparece el error. Aquí está la cadena con esta palabra:

 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 

Mi pregunta es ¿por qué aparece el error?

Aquí está la salida del serialize($this) ejecutada contra el texto sin la palabra journey

Aquí está la salida del serialize($this) ejecutada contra el texto con el journey la palabra

ACTUALIZAR

La tabla en la que estoy guardando el objeto tiene el conjunto de caracteres utf-8 y la columna sin juego de caracteres definido, ya que es de tipo BLOB. El mb_detect_encoding(serialize($this)) devuelve UTF-8

No hay escapatoria para $sql . Así es como se ejecuta la consulta dentro del framework Kohana que estoy usando:

 $result = mysql_query($sql, $this->_connection) 

Respuesta original:

Un campo TEXT en MySQL almacena hasta 65535 bytes, así que supongo que está siendo truncado allí.

Use un MEDIUMTEXT o LONGTEXT en su lugar.

Además de eso, hay problemas potenciales con la forma de obtener los datos dentro y fuera de la base de datos. Las cadenas serializadas PHP pueden contener bytes nulos (el byte 0) y eso parece ser lo que no se transfiere correctamente.

Una forma de evitar esto es codificar la cadena a través de algo como base64_encode() que utiliza un alfabeto alfanumérico / símbolo muy amigable. Eso resolverá sus problemas si aumenta su tipo BLOB a MEDIUMBLOB o LONGBLOB .

Sin embargo, si envía correctamente sus consultas a la base de datos, puede enviar la cadena original de manera segura. Como está usando Kohana, aquí hay una muestra que funciona perfectamente bien para mí.

Version corta:

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

Código:

  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:

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

Esquema:

 CREATE TABLE `serialized_object` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `data` longblob NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 

El problema se soluciona con este enfoque:

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

Pero la pregunta sigue siendo, ¿cuáles son las causas de los errores encontrados por la función de Baba findSerializeError ?