Estoy usando Hotaru CMS con el complemento Image Upload, obtengo este error si intento adjuntar una imagen a una publicación, de lo contrario no hay error:
unserialize () [function.unserialize]: Error en el desplazamiento
El código infractor (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 final tiene la información de la imagen, no soy un experto en PHP, así que me preguntaba qué pensarían ustedes.
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 encontré 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;
}
php
mysql
serialization
content-management-system
usuario576820
fuente
fuente
@unserialize($product->des_txtmopscol);
@
no es resolver errores, es silenciar errores - nada en realidad "se arregla" con esa técnica.Respuestas:
unserialize() [function.unserialize]: Error at offset
fueinvalid serialization data
debido a una longitud no válidaArreglo rapido
Lo que puede hacer es
recalculating the length
de los elementos en una matriz serializadaSus datos serializados actuales
Ejemplo sin recálculo
Salida
Recalcular
Salida
Recomendación ... I
En lugar de utilizar este tipo de solución rápida ... le aconsejaré que actualice la pregunta con
Cómo está serializando sus datos
Cómo lo está guardando ...
================================ EDITAR 1 ================ ===============
El error
El error se generó debido al uso de comillas dobles en
"
lugar de comillas simples,'
por lo queC:\fakepath\100.png
se convirtió aC:fakepath100.jpg
Para corregir el error
Necesitas cambiar de
$h->vars['submitted_data']
(nota el chamuscado bastante'
)Reemplazar
Con
Filtro adicional
También puede agregar este filtro simple antes de llamar a serialize
Si tiene caracteres UTF, también puede ejecutar
Cómo detectar el problema en futuros datos serializados
Salida
findSerializeError
FunciónUna mejor forma de guardar en la base de datos
fuente
findSerializeError
función y encontré muchos errores. Por favor, eche un vistazo a mi temabase64
en el artículo antes de agregarlo a la base de datos ... conservaría el carácter nuloNo tengo suficiente reputación para comentar, así que espero que las personas que usan la respuesta "correcta" anterior lo vean:
Desde php 5.5, el modificador / e en preg_replace () ha quedado obsoleto por completo y el preg_match anterior generará un error. 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.
fuente
strlen()
y, por lo tanto, realiza llamadas de función redundantes. Personalmente, considero que la adición de una condición en línea es demasiado detallada, pero este fragmento está haciendo cosas buenas por buenas razones.'!s:(\d+):"(.*?)";!s'
(con una terminación 's' para tomar nuevas líneas también). Gracias al comentario de adilbo a continuación.Hay otra razón por la que
unserialize()
falló porque colocó incorrectamente datos serializados en la base de datos, consulte la Explicación oficial aquí. Dado queserialize()
devuelve datos binarios y variables php no les importa los métodos de codificación, por lo que ponerlos en TEXT, VARCHAR () causará este error.Solución: almacene los datos serializados en BLOB en su tabla.
fuente
image
valor. Su respuesta no corresponde a la pregunta específica del OP. Es posible que desee trasladar su consejo a: stackoverflow.com/q/5544749/2943403Arreglo rapido
Recalcular la longitud de los elementos en una matriz serializada, pero no use (preg_replace) está en desuso, mejor use preg_replace_callback:
Editar: La nueva versión ahora no solo tiene una longitud incorrecta, sino que también corrige los saltos de línea y cuenta los caracteres correctos con un acento (gracias a mickmackusa )
fuente
Este error se debe a que su juego de caracteres es incorrecto.
Establecer juego de caracteres después de la etiqueta abierta:
Y establezca charset utf8 en su base de datos:
fuente
image
valor y no pudo actualizar el recuento de bytes. A menos que se me informe lo contrario, debo asumir que esta respuesta es incorrecta para la pregunta del OP.Puede reparar la cadena de serialización rota usando la siguiente función, con manejo de caracteres multibyte .
fuente
mb_strlen()
es inapropiado porqueserialize()
almacena el recuento de bytes, no el recuento de caracteres. Editar su respuesta para que sea correcta solo crearía consejos redundantes en la página.función pública unserializeKeySkills ($ string) {
fuente
trim()
cada subcadena coincidente. Ese solo punto hace que esta solución sea imposible de recomendar. Además, se ahogará con los caracteres de nueva línea y capturará innecesariamente el recuento de bytes preexistente que simplemente se sobrescribirá de todos modos. Finalmente, esta es una "respuesta de solo código" y este tipo de respuestas son de bajo valor, ya que hacen poco para educar / empoderar a los futuros investigadores.No puede arreglar una cadena de serialización rota usando las expresiones regulares propuestas:
Puede reparar la cadena de serialización rota usando la siguiente expresión regular:
Salida
o
fuente
los documentos oficiales dicen que debería devolver falso y establecer E_NOTICE
pero como tiene un error, el informe de errores está configurado para ser activado por E_NOTICE
aquí hay una solución para permitirle detectar falso devuelto por
unserialize
es posible que desee considerar el uso de codificación / decodificación base64
fuente
base64_encode
hizo el truco para mí. En mi caso, estamos pasandoserialize
d datos a través de la línea de comando y parece que algunos caracteres extraños impiden que funcione correctamente.base64_encode()
no es la solución a la pregunta formulada por el OP. La pregunta / problema del OP trata específicamente del hecho de que (probablemente suceda con un reemplazo inapropiado de subcadena en el "elemento de matriz final" de la cadena serializada) hay un recuento incorrecto de bytes en la cadena serializada. Por favor, solo publique respuestas que traten directamente la pregunta formulada.La corrupción en esta pregunta se aísla a una sola subcadena al final de la cadena serializada y probablemente fue reemplazada manualmente por alguien que perezosamente quería actualizar el
image
nombre del archivo. Este hecho será evidente en mi enlace de demostración a continuación utilizando los datos publicados del OP; en resumen,C:fakepath100.jpg
no tiene una longitud de19
, debería ser17
.Dado que la corrupción de la cadena serializada se limita a un número de recuento de bytes / caracteres incorrecto, lo siguiente hará un buen trabajo al actualizar la cadena dañada con el valor de recuento de bytes correcto.
El siguiente reemplazo basado en expresiones regulares solo será efectivo para remediar los recuentos de bytes, nada más.
Parece que muchas de las publicaciones anteriores solo están copiando y pegando un patrón de expresiones regulares de otra persona. No hay razón para capturar el número de recuento de bytes potencialmente dañado si no se va a utilizar en el reemplazo. Además, agregar el
s
modificador de patrón es una inclusión razonable en caso de que un valor de cadena contenga nuevas líneas / retornos de línea.* Para aquellos que no están al tanto del tratamiento de caracteres multibyte con serialización, no deben usar
mb_strlen()
en la devolución de llamada personalizada porque es el recuento de bytes lo que se almacena, no el recuento de caracteres , vea mi salida ...Código: ( Demo con datos de OP ) ( Demo con datos de muestra arbitrarios ) ( Demo con reemplazo de condición )
Salida:
Una pierna por la madriguera del conejo ... Lo anterior funciona bien incluso si aparecen comillas dobles en un valor de cadena, pero si un valor de cadena contiene
";
o algún otro sbustring desgarrador, tendrá que ir un poco más allá e implementar "alternativas". Mi nuevo patróncomprueba que el líder
s
es:;
y comprueba que
";
es:}
os:
oi:
No he probado todas y cada una de las posibilidades; de hecho, no estoy relativamente familiarizado con todas las posibilidades en una cadena serializada porque nunca elijo trabajar con datos serializados, siempre json en aplicaciones modernas. Si hay otros posibles caracteres iniciales o finales, deje un comentario y ampliaré las revisiones.
Fragmento extendido: ( demostración )
Salida:
fuente
Tendrá que modificar el tipo de clasificación ay se
utf8_unicode_ci
solucionará el problema.fuente
utf8_unicode_ci
? Tengo mis dudas sobre este.En mi caso, estaba almacenando datos serializados en el
BLOB
campo de MySQL DB que aparentemente no era lo suficientemente grande como para contener el valor completo y lo truncó. Obviamente, una cadena de este tipo no puede ser anulada.Una vez convertido ese campo en
MEDIUMBLOB
el problema se disipó. También puede ser necesario cambiar las opciones de tablaROW_FORMAT
aDYNAMIC
oCOMPRESSED
.fuente
TEXT
campo y, como tal, se truncó en 65kb.Después de haber intentado algunas cosas en esta página sin éxito, eché un vistazo a la fuente de la página y comenté que todas las citas en la cadena serializada han sido reemplazadas por entidades html. Decodificar estas entidades ayuda a evitar muchos dolores de cabeza:
fuente
Aquí hay una herramienta en línea para reparar una cadena serializada dañada.
Me gustaría añadir que esto sucede sobre todo debido a una búsqueda y reemplazo realiza sobre la serialización de los datos (DB y especialmente la
key length
) no se actualiza según el reemplazar y que hace que la "corrupción".No obstante, la herramienta anterior utiliza la siguiente lógica para corregir los datos de serialización ( copiados desde aquí ).
fuente
Otra razón de este problema puede ser el tipo de columna de la tabla de sesiones de "carga útil". Si tiene una gran cantidad de datos sobre la sesión, una columna de texto no sería suficiente. Necesitará MEDIUMTEXT o incluso LONGTEXT.
fuente