unserialize serialize online form errorexception error deserializar checker bytes array and php mysql content-management-system

php - online - unserialize(): error at offset 0 of 40 bytes laravel



unserialize()[function.unserialize]: Error en el desplazamiento (14)

Deberá modificar el tipo de intercalación para utf8_unicode_ci y el problema se solucionará.

Estoy usando Hotaru CMS con el plugin de carga de imágenes. Recibo este error si intento adjuntar una imagen a una publicación; de lo contrario, no hay ningún error.

El código ofensivo (el error apunta a la línea con **):

/** * Retrieve submission step data * * @param $key - empty when setting * @return bool */ public function loadSubmitData($h, $key = '''') { // delete everything in this table older than 30 minutes: $this->deleteTempData($h->db); if (!$key) { return false; } $cleanKey = preg_replace(''/[^a-z0-9]+/'','''',$key); if (strcmp($key,$cleanKey) != 0) { return false; } else { $sql = "SELECT tempdata_value FROM " . TABLE_TEMPDATA . " WHERE tempdata_key = %s ORDER BY tempdata_updatedts DESC LIMIT 1"; $submitted_data = $h->db->get_var($h->db->prepare($sql, $key)); **if ($submitted_data) { return unserialize($submitted_data); } else { return false; }** } }

Datos de la tabla, observe que el bit del final tiene la información de la imagen, no soy un experto en PHP, así que me preguntaba qué pensarían ustedes / chicas.

tempdata_value:

a:10:{s:16:"submit_editorial";b:0;s:15:"submit_orig_url";s:13:"www.bbc.co.uk";s:12:"submit_title";s:14:"No title found";s:14:"submit_content";s:12:"dnfsdkfjdfdf";s:15:"submit_category";i:2;s:11:"submit_tags";s:3:"bbc";s:9:"submit_id";b:0;s:16:"submit_subscribe";i:0;s:15:"submit_comments";s:4:"open";s:5:"image";s:19:"C:fakepath100.jpg";}

Editar: Creo que he encontrado el bit de serialización ...

/** * Save submission step data * * @return bool */ public function saveSubmitData($h) { // delete everything in this table older than 30 minutes: $this->deleteTempData($h->db); $sid = preg_replace(''/[^a-z0-9]+/i'', '''', session_id()); $key = md5(microtime() . $sid . rand()); $sql = "INSERT INTO " . TABLE_TEMPDATA . " (tempdata_key, tempdata_value, tempdata_updateby) VALUES (%s,%s, %d)"; $h->db->query($h->db->prepare($sql, $key, serialize($h->vars[''submitted_data'']), $h->currentUser->id)); return $key; }


Después de haber intentado algunas cosas en esta página sin éxito, eché un vistazo a la fuente de la página y remarqué que todas las comillas en la cadena serializada han sido reemplazadas por entidades html. La decodificación de estas entidades ayuda a evitar muchos dolores de cabeza:

$myVar = html_entity_decode($myVar);


En mi caso, estaba almacenando datos serializados en el campo BLOB de MySQL DB que aparentemente no era lo suficientemente grande como para contener el valor completo y truncarlo. Tal cadena, obviamente, no podría ser deserializada.
Una vez convertido ese campo en MEDIUMBLOB el problema se disipa. También puede ser necesario cambiar las opciones de tabla ROW_FORMAT a DYNAMIC o COMPRESSED .


Enfrenté el mismo problema mientras deserializaba los datos. Descubrí que si hay un ",", "o" en cualquiera de los valores de la matriz, la serialización se corrompe. Tuve una: en mi matriz, así que la eliminé y se corrigió.

Espero que ayude a alguien.


Este error se debe a que su juego de caracteres está equivocado.

Establecer charset después de abrir la etiqueta:

header(''Content-Type: text/html; charset=utf-8'');

Y configure charset utf8 en su base de datos:

mysql_query("SET NAMES ''utf8''");


Hay otro motivo por el cual unserialize() falló porque usted ingresó incorrectamente datos serializados en la base de datos, vea Explicación Oficial aquí. Dado que serialize() devuelve datos binarios y las variables php no se preocupan por los métodos de codificación, por lo que ponerlo en TEXT, VARCHAR () causará este error.

Solución: almacene datos serializados en BLOB en su tabla.


No tengo suficiente reputación para comentar, por lo que espero que las personas que utilizan la respuesta "correcta" anterior lo vean:

Desde php 5.5, el modificador / e en preg_replace () ha quedado en desuso por completo y el preg_match anterior tendrá un error de salida. La documentación de php recomienda usar preg_match_callback en su lugar.

Encuentre la siguiente solución como alternativa al preg_match propuesto anteriormente.

$fixed_data = preg_replace_callback ( ''!s:(/d+):"(.*?)";!'', function($match) { return ($match[1] == strlen($match[2])) ? $match[0] : ''s:'' . strlen($match[2]) . '':"'' . $match[2] . ''";''; },$bad_data );


Otra razón de este problema puede ser el tipo de columna de la tabla de sesiones de "carga útil". Si tiene datos enormes en la sesión, una columna de texto no sería suficiente. Necesitará MEDIUMTEXT o incluso LONGTEXT.


Puede reparar cadenas de serialización rotas usando la siguiente función, con manejo de caracteres multibyte .

function repairSerializeString($value) { $regex = ''/s:([0-9]+):"(.*?)"/''; return preg_replace_callback( $regex, function($match) { return "s:".mb_strlen($match[2]).":/"".$match[2]."/""; }, $value ); }


función pública unserializeKeySkills ($ string) {

$output = array(); $string = trim(preg_replace(''//s/s+/'', '' '',$string)); $string = preg_replace_callback(''!s:(/d+):"(.*?)";!'', function($m) { return ''s:''.strlen($m[2]).'':"''.$m[2].''";''; }, utf8_encode( trim(preg_replace(''//s/s+/'', '' '',$string)) )); try { $output = unserialize($string); } catch (/Exception $e) { /Log::error("unserialize Data : " .print_r($string,true)); } return $output; }


los documentos oficiales dicen que debe devolver falso y establecer E_NOTICE

pero dado que tienes un error, E_NOTICE debe activar el informe de errores

aquí hay una solución para permitirle detectar falso devuelto por la unserialize

$old_err=error_reporting(); error_reporting($old_err & ~E_NOTICE); $object = unserialize($serialized_data); error_reporting($old_err);

es posible que desee considerar el uso de codificación / decodificación base64

$string=base64_encode(serialize($obj)); unserialize(base64_decode($string));


unserialize() [function.unserialize]: Error at offset se debió a invalid serialization data debido a una longitud no válida

Arreglo rapido

Lo que puede hacer es recalculating the length de los elementos en una matriz serializada

Sus datos serializados actuales

$data = ''a:10:{s:16:"submit_editorial";b:0;s:15:"submit_orig_url";s:13:"www.bbc.co.uk";s:12:"submit_title";s:14:"No title found";s:14:"submit_content";s:12:"dnfsdkfjdfdf";s:15:"submit_category";i:2;s:11:"submit_tags";s:3:"bbc";s:9:"submit_id";b:0;s:16:"submit_subscribe";i:0;s:15:"submit_comments";s:4:"open";s:5:"image";s:19:"C:fakepath100.jpg";}'';

Ejemplo sin recálculo

var_dump(unserialize($data));

Salida

Notice: unserialize() [function.unserialize]: Error at offset 337 of 338 bytes

Recalculando

$data = preg_replace(''!s:(/d+):"(.*?)";!e'', "''s:''.strlen(''$2'').'':/"$2/";''", $data); var_dump(unserialize($data));

Salida

array ''submit_editorial'' => boolean false ''submit_orig_url'' => string ''www.bbc.co.uk'' (length=13) ''submit_title'' => string ''No title found'' (length=14) ''submit_content'' => string ''dnfsdkfjdfdf'' (length=12) ''submit_category'' => int 2 ''submit_tags'' => string ''bbc'' (length=3) ''submit_id'' => boolean false ''submit_subscribe'' => int 0 ''submit_comments'' => string ''open'' (length=4) ''image'' => string ''C:fakepath100.jpg'' (length=17)

Recomendación .. I

En lugar de usar este tipo de solución rápida ... te aconsejo que actualices la pregunta con

  • Cómo está serializando sus datos

  • Cómo lo estás Guardando ...

============================= EDITAR 1 ================ ===============

El error

El error se generó debido al uso de comillas dobles " lugar de comillas simples '' es por eso que C:/fakepath/100.png se convirtió a C:fakepath100.jpg

Para arreglar el error

Necesita cambiar $h->vars[''submitted_data''] (tenga en cuenta el chamuscado bastante '' )

Reemplazar

$h->vars[''submitted_data''][''image''] = "C:/fakepath/100.png" ;

Con

$h->vars[''submitted_data''][''image''] = ''C:/fakepath/100.png'' ;

Filtro adicional

También puede agregar este filtro simple antes de llamar a serializar

function satitize(&$value, $key) { $value = addslashes($value); } array_walk($h->vars[''submitted_data''], "satitize");

Si tiene caracteres UTF también puede ejecutar

$h->vars[''submitted_data''] = array_map("utf8_encode",$h->vars[''submitted_data'']);

Cómo detectar el problema en futuros datos serializados

findSerializeError ( $data1 ) ;

Salida

Diffrence 9 != 7 -> ORD number 57 != 55 -> Line Number = 315 -> Section Data1 = pen";s:5:"image";s:19:"C:fakepath100.jpg -> Section Data2 = pen";s:5:"image";s:17:"C:fakepath100.jpg ^------- The Error (Element Length)

Función findSerializeError

function findSerializeError($data1) { echo "<pre>"; $data2 = preg_replace ( ''!s:(/d+):"(.*?)";!e'', "''s:''.strlen(''$2'').'':/"$2/";''",$data1 ); $max = (strlen ( $data1 ) > strlen ( $data2 )) ? strlen ( $data1 ) : strlen ( $data2 ); echo $data1 . PHP_EOL; echo $data2 . PHP_EOL; for($i = 0; $i < $max; $i ++) { if (@$data1 {$i} !== @$data2 {$i}) { echo "Diffrence ", @$data1 {$i}, " != ", @$data2 {$i}, PHP_EOL; echo "/t-> ORD number ", ord ( @$data1 {$i} ), " != ", ord ( @$data2 {$i} ), PHP_EOL; echo "/t-> Line Number = $i" . PHP_EOL; $start = ($i - 20); $start = ($start < 0) ? 0 : $start; $length = 40; $point = $max - $i; if ($point < 20) { $rlength = 1; $rpoint = - $point; } else { $rpoint = $length - 20; $rlength = 1; } echo "/t-> Section Data1 = ", substr_replace ( substr ( $data1, $start, $length ), "<b style=/"color:green/">{$data1 {$i}}</b>", $rpoint, $rlength ), PHP_EOL; echo "/t-> Section Data2 = ", substr_replace ( substr ( $data2, $start, $length ), "<b style=/"color:red/">{$data2 {$i}}</b>", $rpoint, $rlength ), PHP_EOL; } } }

Una mejor forma de guardar en la base de datos

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


Arreglo rapido

Al volver a calcular la longitud de los elementos en la matriz serializada, pero no usa (preg_replace) está obsoleto, mejor use preg_replace_callback:

$data = preg_replace_callback(''!s:(/d+):"(.*?)";!'', function($m) { return ''s:''.mb_strlen($m[2]).'':"''.$m[2].''";''; }, $data);


$badData = ''a:2:{i:0;s:16:"as:45:"d"; Is /n";i:1;s:19:"as:45:"d"; Is /r/n";}'';

No puede arreglar una cadena de serialización rota utilizando las expresiones regulares propuestas:

$data = preg_replace(''!s:(/d+):"(.*?)";!e'', "''s:''.strlen(''$2'').'':/"$2/";''", $badData); var_dump(@unserialize($data)); // Output: bool(false) // or $data = preg_replace_callback( ''/s:(/d+):"(.*?)";/'', function($m){ return ''s:'' . mb_strlen($m[2]) . '':"'' . $m[2] . ''";''; }, $badData ); var_dump(@unserialize($data)); // Output: bool(false)

Puede reparar cadenas de serialización rotas usando la siguiente expresión regular:

$data = preg_replace_callback( ''/(?<=^|/{|;)s:(/d+):/"(.*?)/";(?=[asbdiO]/:/d|N;|/}|$)/s'', function($m){ return ''s:'' . mb_strlen($m[2]) . '':"'' . $m[2] . ''";''; }, $badData ); var_dump(@unserialize($data));

Salida

array(2) { [0] => string(17) "as:45:"d"; Is /n" [1] => string(19) "as:45:"d"; Is /r/n" }

o

array(2) { [0] => string(16) "as:45:"d"; Is /n" [1] => string(18) "as:45:"d"; Is /r/n" }