Estou usando o Hotaru CMS com o plugin de upload de imagem, recebo este erro se tento anexar uma imagem a uma postagem, caso contrário, não há erro:
unserialize () [function.unserialize]: Erro no deslocamento
O código ofensivo (o erro aponta para a linha com **):
/**
* 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; }**
}
}
Dados da tabela, observe que o bit final contém as informações da imagem. Não sou um especialista em PHP, então queria saber o que vocês / garotas podem pensar?
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";}
Edit: Acho que encontrei a parte serializar ...
/**
* 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
user576820
fonte
fonte
@unserialize($product->des_txtmopscol);
@
não é uma solução de erro, é um silenciamento de erro - nada realmente "fica consertado" com essa técnica.Respostas:
unserialize() [function.unserialize]: Error at offset
eram dívidasinvalid serialization data
devido ao comprimento inválidoConserto rápido
O que você pode fazer é colocar
recalculating the length
os elementos em uma matriz serializadaSeus dados serializados atuais
Exemplo sem recálculo
Resultado
Recalculando
Resultado
Recomendação .. eu
Em vez de usar este tipo de solução rápida ... aconselho você a atualizar a questão com
Como você está serializando seus dados
Como você está salvando ..
==================================== EDITAR 1 ================ ===============
O erro
O erro foi gerado devido ao uso de aspas duplas em
"
vez de aspas simples,'
por issoC:\fakepath\100.png
foi convertido paraC:fakepath100.jpg
Para consertar o erro
Você precisa mudar
$h->vars['submitted_data']
de (Observe o singe'
)Substituir
Com
Filtro Adicional
Você também pode adicionar este filtro simples antes de chamar serializar
Se você tiver caracteres UTF, também pode executar
Como detectar o problema em dados serializados futuros
Resultado
findSerializeError
FunçãoA melhor maneira de salvar no banco de dados
fonte
findSerializeError
função incrível e encontrei muitos erros. Por favor, dê uma olhada no meu tópicobase64
no Artigo antes de adicioná-lo ao banco de dados ... preservaria o caractere nuloNão tenho reputação suficiente para comentar, então espero que isso seja visto por pessoas que usam a resposta "correta" acima:
Desde o php 5.5, o modificador / e em preg_replace () se tornou completamente obsoleto e o preg_match acima apresentará um erro. A documentação do php recomenda usar preg_match_callback em seu lugar.
Encontre a seguinte solução como uma alternativa para o preg_match proposto acima.
fonte
strlen()
e, portanto, faz chamadas de função redundantes. Pessoalmente, acho que a adição de uma condição inline é muito detalhada, mas esse snippet está fazendo coisas boas por bons motivos.'!s:(\d+):"(.*?)";!s'
(com uma terminação 's' para incluir novas linhas também). Obrigado ao comentário de adilbo abaixo.Há outro motivo para a
unserialize()
falha porque você colocou dados serializados incorretamente no banco de dados, consulte a Explicação oficial aqui. Visto queserialize()
retorna dados binários e variáveis php não se importam com os métodos de codificação, então colocá-los em TEXT, VARCHAR () causará este erro.Solução: armazene dados serializados em BLOB em sua tabela.
fonte
image
valor. Sua resposta não pertence à pergunta específica do OP. Você pode querer mover seu conselho para: stackoverflow.com/q/5544749/2943403Conserto rápido
Recalcular o comprimento dos elementos na matriz serializada - mas não use (preg_replace) está obsoleto - é melhor usar preg_replace_callback:
Edit: New Version agora não apenas comprimento errado, mas também corrige quebras de linha e conta os caracteres corretos com aczent (graças a mickmackusa )
fonte
Este erro é causado porque seu conjunto de caracteres está errado.
Definir conjunto de caracteres após abrir a tag:
E defina o conjunto de caracteres utf8 em seu banco de dados:
fonte
image
valor e não atualizou a contagem de bytes. A menos que informado de outra forma, devo presumir que essa resposta está incorreta para a pergunta do OP.Você pode consertar string serializada quebrada usando a seguinte função, com tratamento de caracteres multibyte .
fonte
mb_strlen()
é inadequado porqueserialize()
armazena a contagem de bytes, não a contagem de caracteres. Editar sua resposta para ser correta apenas criaria conselhos redundantes na página.public function unserializeKeySkills ($ string) {
fonte
trim()
cada substring correspondente. Esse ponto por si só torna impossível recomendar essa solução. Além disso, ele vai engasgar com caracteres de nova linha e desnecessariamente captura a contagem de bytes pré-existente que será substituída de qualquer maneira. Finalmente, esta é uma "resposta apenas em código" e esses tipos de respostas são de baixo valor, pois fazem pouco para educar / capacitar futuros pesquisadores.Você não pode consertar uma string serializada quebrada usando os regexes propostos:
Você pode consertar string serializada quebrada usando o seguinte regex:
Resultado
ou
fonte
os documentos oficiais diz que ele deve retornar falso e definir E_NOTICE
mas como você obteve o erro, o relatório de erro está configurado para ser acionado por E_NOTICE
aqui está uma correção para permitir que você detecte falso retornado por
unserialize
você pode querer considerar o uso de codificação / decodificação base64
fonte
base64_encode
fez o truque para mim. No meu caso, estamos passandoserialize
dados d pela linha de comando e parecia que alguns caracteres estranhos estavam impedindo o funcionamento correto.base64_encode()
não é a solução para a pergunta do OP. A questão / problema do OP está especificamente relacionado ao fato de que (provavelmente devido a uma substituição inadequada de substring no "elemento final da matriz" da string serializada) há uma contagem incorreta de bytes na string serializada. Por favor, poste apenas respostas que lidem diretamente com a pergunta feita.A corrupção nesta questão está isolada em uma única substring no final da string serializada com provavelmente foi substituída manualmente por alguém que preguiçosamente queria atualizar o
image
nome do arquivo. Esse fato ficará aparente em meu link de demonstração abaixo usando os dados postados do OP - em suma,C:fakepath100.jpg
não tem um comprimento de19
, deveria ser17
.Uma vez que a corrupção da string serializada é limitada a um número de contagem de byte / caractere incorreto, o seguinte fará um bom trabalho de atualização da string corrompida com o valor de contagem de bytes correto.
A seguinte substituição baseada em regex só será eficaz para corrigir contagens de bytes, nada mais.
Parece que muitas das postagens anteriores estão apenas copiando e colando um padrão regex de outra pessoa. Não há razão para capturar o número de contagem de bytes potencialmente corrompido se ele não for usado na substituição. Além disso, adicionando o
s
modificador de padrão é uma inclusão razoável caso um valor de string contenha novas linhas / retornos de linha.* Para aqueles que não estão cientes do tratamento de caracteres multibyte com serialização, você não deve usar
mb_strlen()
no retorno de chamada personalizado porque é a contagem de bytes que é armazenada, não a contagem de caracteres , veja minha saída ...Código: ( Demo com dados do OP ) ( Demo com dados de amostra arbitrários ) ( Demo com substituição de condição )
Resultado:
Uma perna abaixo da toca do coelho ... O procedimento acima funciona bem mesmo se as aspas duplas ocorrerem em um valor de string, mas se um valor de string contiver
";
procedimento algum outro símbolo assustador, você precisará ir um pouco além e implementar "lookarounds". Meu novo padrãoverifica se o líder
s
é:;
e verifica se o
";
é:}
ous:
oui:
Não testei todas as possibilidades; na verdade, não estou familiarizado com todas as possibilidades em uma string serializada porque nunca optei por trabalhar com dados serializados - sempre json em aplicativos modernos. Se houver caracteres adicionais possíveis à esquerda ou à direita, deixe um comentário e estenderei as alternativas.
Snippet estendido: ( Demo )
Resultado:
fonte
Você terá que alterar o tipo de agrupamento para
utf8_unicode_ci
e o problema será corrigido.fonte
utf8_unicode_ci
? Eu tenho minhas dúvidas sobre este.No meu caso, eu estava armazenando dados serializados no
BLOB
campo do banco de dados MySQL que aparentemente não era grande o suficiente para conter o valor inteiro e o truncou. Obviamente, tal string não poderia ser desserializada.Uma vez convertido esse campo,
MEDIUMBLOB
o problema se dissipou. Também pode ser necessário alternar as opções da tabelaROW_FORMAT
paraDYNAMIC
ouCOMPRESSED
.fonte
TEXT
campo e, como tal, truncado em 65kb.Depois de tentar algumas coisas nesta página sem sucesso, dei uma olhada no código-fonte da página e observei que todas as citações na string serializada foram substituídas por entidades html. A decodificação dessas entidades ajuda a evitar muitas dores de cabeça:
fonte
Aqui está uma ferramenta online para corrigir uma string serializada corrompida.
Eu gostaria de acrescentar que isso acontece principalmente devido a uma busca e substituição feita no banco de dados e os dados de serialização ( especialmente o
key length
) não são atualizados de acordo com a substituição e isso causa a "corrupção".No entanto, a ferramenta acima usa a seguinte lógica para corrigir os dados de serialização ( copiado daqui ).
fonte
Outra razão para este problema pode ser o tipo de coluna da tabela de sessões de "carga útil". Se você tiver muitos dados sobre a sessão, uma coluna de texto não será suficiente. Você precisará do MEDIUMTEXT ou mesmo do LONGTEXT.
fonte