J'utilise Hotaru CMS avec le plugin Image Upload, j'obtiens cette erreur si j'essaye de joindre une image à une publication, sinon il n'y a pas d'erreur:
unserialize () [function.unserialize]: Erreur au décalage
Le code incriminé (l'erreur pointe vers la ligne avec **):
/**
* 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; }**
}
}
Les données du tableau, notez que le bit de fin contient les informations sur l'image, je ne suis pas un expert en PHP, alors je me demandais ce que vous pourriez penser?
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: Je pense avoir trouvé le bit de sérialisation ...
/**
* 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
la source
la source
@unserialize($product->des_txtmopscol);
@
ne résout pas les erreurs, c'est la suppression des erreurs - rien n'est réellement "corrigé" avec cette technique.Réponses:
unserialize() [function.unserialize]: Error at offset
la cotisation étaitinvalid serialization data
due à une longueur invalideSolution rapide
Ce que vous pouvez faire est
recalculating the length
des éléments dans un tableau sérialiséVos données sérialisées actuelles
Exemple sans recalcul
Production
Recalculer
Production
Recommandation .. I
Au lieu d'utiliser ce type de solution rapide ... je vous conseille de mettre à jour la question avec
Comment vous sérialisez vos données
Comment vous le sauvegardez.
================================= EDIT 1 ================ ===============
L'erreur
L'erreur a été générée en raison de l'utilisation de guillemets doubles
"
au lieu de guillemets simples,'
c'est pourquoi aC:\fakepath\100.png
été convertie enC:fakepath100.jpg
Pour corriger l'erreur
Vous devez changer de
$h->vars['submitted_data']
(notez le singe assez'
)Remplacer
Avec
Filtre supplémentaire
Vous pouvez également ajouter ce filtre simple avant d'appeler sérialiser
Si vous avez des caractères UTF, vous pouvez également exécuter
Comment détecter le problème dans les futures données sérialisées
Production
findSerializeError
FonctionUne meilleure façon d'enregistrer dans la base de données
la source
findSerializeError
fonction incroyable et j'ai trouvé beaucoup d'erreurs. S'il vous plaît jeter un oeil à mon sujetbase64
sur l'article avant de l'ajouter à la base de données ... cela conserverait le caractère nulJe n'ai pas assez de réputation pour commenter, alors j'espère que les personnes qui utilisent la réponse "correcte" ci-dessus le verront:
Depuis php 5.5, le modificateur / e dans preg_replace () a été complètement obsolète et le preg_match ci-dessus sera une erreur. La documentation php recommande d'utiliser preg_match_callback à sa place.
Veuillez trouver la solution suivante comme alternative au preg_match proposé ci-dessus.
la source
strlen()
et effectue donc des appels de fonction redondants. Personnellement, je trouve l'ajout d'une condition en ligne trop verbeux, mais cet extrait de code fait de bonnes choses pour de bonnes raisons.'!s:(\d+):"(.*?)";!s'
(avec une fin 's' pour prendre également de nouvelles lignes). Merci au commentaire d'adilbo ci-dessous.Il y a une autre raison qui a
unserialize()
échoué parce que vous avez mal mis des données sérialisées dans la base de données, voir l' explication officielle ici. Puisqueserialize()
renvoie les données binaires et les variables php ne se soucient pas des méthodes de codage, de sorte que le mettre dans TEXT, VARCHAR () provoquera cette erreur.Solution: stockez les données sérialisées dans BLOB dans votre table.
la source
image
valeur. Votre réponse ne concerne pas la question spécifique du PO. Vous pouvez déplacer vos conseils sur: stackoverflow.com/q/5544749/2943403Solution rapide
Recalculer la longueur des éléments dans un tableau sérialisé - mais n'utilisez pas (preg_replace) c'est obsolète - mieux utiliser preg_replace_callback:
Edit: Nouvelle version maintenant non seulement une mauvaise longueur, mais elle corrige également les sauts de ligne et compte les caractères corrects avec aczent (grâce à mickmackusa )
la source
Cette erreur est due au fait que votre jeu de caractères est incorrect.
Définir le jeu de caractères après la balise ouverte:
Et définissez charset utf8 dans votre base de données:
la source
image
valeur et n'a pas réussi à mettre à jour le nombre d'octets. Sauf indication contraire, je dois supposer que cette réponse est incorrecte pour la question du PO.Vous pouvez corriger une chaîne de sérialisation cassée en utilisant la fonction suivante, avec la gestion des caractères multi-octets .
la source
mb_strlen()
c'est inapproprié carserialize()
stocke le nombre d'octets, pas le nombre de caractères. Modifier votre réponse pour qu'elle soit correcte ne créerait que des conseils redondants sur la page.public function unserializeKeySkills ($ string) {
la source
trim()
chaque sous-chaîne correspondante. Ce seul point rend cette solution impossible à recommander. De plus, il s'étouffera avec les caractères de nouvelle ligne et capture inutilement le nombre d'octets préexistant qui va juste être écrasé de toute façon. Enfin, il s'agit d'une «réponse codée uniquement» et ces types de réponses sont de faible valeur car ils ne contribuent guère à éduquer / autonomiser les futurs chercheurs.Vous ne pouvez pas réparer une chaîne de sérialisation cassée à l'aide des expressions régulières proposées:
Vous pouvez corriger la chaîne de sérialisation cassée à l'aide de l'expression régulière suivante:
Production
ou
la source
les documents officiels dit qu'il devrait retourner false et définir E_NOTICE
mais comme vous avez une erreur, le rapport d'erreur est configuré pour être déclenché par E_NOTICE
voici un correctif pour vous permettre de détecter les faux retournés par
unserialize
vous voudrez peut-être envisager d'utiliser l'encodage / décodage base64
la source
base64_encode
a fait l'affaire pour moi. Dans mon cas, nous transmettons desserialize
données sur la ligne de commande et il semblait que des caractères étranges l'empêchaient de fonctionner correctement.base64_encode()
n'est pas la solution à la question posée par le PO. La question / problème de l'OP traite spécifiquement du fait que (probablement en cas de remplacement de sous-chaîne inapproprié sur "l'élément de tableau final" de la chaîne sérialisée) il y a un nombre d'octets incorrect dans la chaîne sérialisée. Veuillez ne publier que des réponses qui traitent directement de la question posée.La corruption dans cette question est isolée sur une seule sous-chaîne à la fin de la chaîne sérialisée avec probablement été remplacée manuellement par quelqu'un qui voulait paresseusement mettre à jour le
image
nom de fichier. Ce fait sera apparent dans mon lien de démonstration ci-dessous en utilisant les données publiées par le PO - en bref, ilC:fakepath100.jpg
n'a pas une longueur de19
, il devrait l'être17
.Étant donné que la corruption de chaîne sérialisée est limitée à un nombre d'octets / caractères incorrect, ce qui suit fera un bon travail de mise à jour de la chaîne corrompue avec la valeur de nombre d'octets correcte.
Le remplacement suivant basé sur les expressions régulières ne sera efficace que pour remédier au nombre d'octets, rien de plus.
Il semble que la plupart des articles précédents ne font que copier-coller un modèle d'expression régulière de quelqu'un d'autre. Il n'y a aucune raison de capturer le nombre d'octets potentiellement corrompu s'il n'est pas utilisé dans le remplacement. Aussi, en ajoutant le
s
modificateur de modèle est une inclusion raisonnable dans le cas où une valeur de chaîne contient des retours à la ligne / des retours de ligne.* Pour ceux qui ne connaissent pas le traitement des caractères multi-octets avec la sérialisation, vous ne devez pas utiliser
mb_strlen()
dans le rappel personnalisé car c'est le nombre d'octets qui est stocké et non le nombre de caractères , voir ma sortie ...Code: ( Démo avec les données de l'OP ) ( Démo avec des exemples de données arbitraires ) ( Démo avec remplacement de condition )
Production:
Une jambe dans le trou du lapin ... Ce qui précède fonctionne bien même si des guillemets doubles apparaissent dans une valeur de chaîne, mais si une valeur de chaîne contient
";
ou quelque autre sbustring de singe, vous devrez aller un peu plus loin et implémenter des "lookarounds". Mon nouveau modèlevérifie que le début
s
est:;
et vérifie que le
";
est:}
ous:
oui:
Je n'ai pas testé toutes les possibilités; en fait, je ne suis relativement pas familier avec toutes les possibilités d'une chaîne sérialisée parce que je n'ai jamais choisi de travailler avec des données sérialisées - toujours json dans les applications modernes. S'il y a d'autres caractères de début ou de fin possibles, laissez un commentaire et je vais étendre les recherches.
Extrait étendu: ( Démo )
Production:
la source
Vous devrez modifier le type de classement
utf8_unicode_ci
et le problème sera résolu.la source
utf8_unicode_ci
? J'ai mes doutes sur celui-ci.Dans mon cas, je stockais des données sérialisées dans le
BLOB
champ de la base de données MySQL qui n'était apparemment pas assez grande pour contenir la valeur entière et je l'ai tronquée. Une telle chaîne ne pouvait évidemment pas être désérialisée.Une fois converti, ce champ en
MEDIUMBLOB
problème s'est dissipé. Il peut également être nécessaire de basculer les options de tableROW_FORMAT
versDYNAMIC
ouCOMPRESSED
.la source
TEXT
champ et en tant que tel tronqué à 65kb.Après avoir essayé certaines choses sur cette page sans succès, j'ai jeté un coup d'œil dans la page-source et j'ai remarqué que toutes les citations de la chaîne sérialisée ont été remplacées par des entités html. Le décodage de ces entités permet d'éviter beaucoup de maux de tête:
la source
Voici un outil en ligne pour réparer une chaîne sérialisée corrompue.
Je voudrais ajouter que cela se produit principalement en raison d'une recherche et d'un remplacement effectués sur la base de données et les données de sérialisation (en particulier le
key length
) ne sont pas mises à jour selon le remplacement et cela provoque la «corruption».Néanmoins, l'outil ci-dessus utilise la logique suivante pour corriger les données de sérialisation ( copiées à partir d'ici ).
la source
Une autre raison de ce problème peut être le type de colonne de la table de sessions "payload". Si vous avez d'énormes données sur la session, une colonne de texte ne suffirait pas. Vous aurez besoin de MEDIUMTEXT ou même de LONGTEXT.
la source