PHP unserialize échoue avec des non-caractères codés?
$ser = 'a:2:{i:0;s:5:"héllö";i:1;s:5:"wörld";}'; //fails
$ser2 = 'a:2:{i:0;s:5:"hello";i:1;s:5:"world";}'; //works
$out = unserialize($ser);
$out2 = unserialize($ser2);
print_r($out);
print_r($out2);
echo "<hr>";
Mais pourquoi?
Dois-je coder avant de serialzing que? Comment?
Je suis à l'aide de Javascript pour écrire la chaîne sérialisée à un champ caché, que PHP $_POST
En JS, j'ai quelque chose comme:
function writeImgData() {
var caption_arr = new Array();
$('.album img').each(function(index) {
caption_arr.push($(this).attr('alt'));
});
$("#hidden-field").attr("value", serializeArray(caption_arr));
};
Vous devez vous connecter pour publier un commentaire.
La raison pour laquelle
unserialize()
échoue avec:Est parce que la longueur de
héllö
etwörld
sont mauvais, car PHP ne gère pas correctement le multi-chaînes d'octets en mode natif:Toutefois, si vous essayez de
unserialize()
la suite de chaîne correcte:Cela fonctionne:
Si vous utilisez PHP
serialize()
correctement calculer les longueurs de chaîne multi-byte index.D'autre part, si vous voulez travailler avec des données sérialisées dans de multiples (programmation) langues, vous devez l'oublier et de passer à quelque chose comme JSON, qui est la façon la plus standardisée.
Je sais que cela a été posté comme il y a un an, mais je viens d'avoir ce problème et de trouver ça, et en fait j'ai trouvé une solution pour elle. Ce bout de code fonctionne comme un charme!
L'idée derrière est facile. Il est juste de vous aider par le recalcul de la longueur des chaînes de caractères multi-octets affichés par @Alix ci-dessus.
Quelques modifications devraient convient à votre code:
Source: http://snippets.dzone.com/posts/show/6592
Testé sur ma machine, et il fonctionne comme un charme!!
???
, mais cette fonction me permet de rendre le code du travail, même avec cela, mercie
modificateur s'en va, le temps de passer à la fonction preg_replace_callback....s:28:"some "quotes"; in the middle";...
après votre fonction sera de retour...s:13:"some \"quotes"; in the middle";...
. C'est l'une des raisons de la serializations a été créé à la première place.Lionel Chan répondre modifié pour fonctionner avec PHP >= 5.5 :
Ce code utilise la fonction preg_replace_callback comme preg_replace avec le modificateur /e est obsolète depuis PHP 5.5.
La question est - comme l'a souligné Alix liées à l'encodage.
Jusqu'à la version PHP 5.4 le codage interne de PHP est l'ISO-8859-1, ce codage utilise un octet pour certains caractères unicode sont multi-octets. Le résultat est que plusieurs octets valeurs sérialisées sur UTF-8, le système ne sera pas lisible sur la norme ISO-8859-1 systèmes.
L'éviter ce type de problèmes, assurez-vous que tous les systèmes d'utiliser le même encodage:
Vous pouvez utiliser
utf8_(encode|decode)
de nettoyage:En réponse à @Lionel ci-dessus, en fait la fonction mb_unserialize() comme vous l'avez proposé ne fonctionne pas si la chaîne sérialisée lui-même contient char séquence
";
(devis, suivi par un point-virgule).À utiliser avec prudence. Par exemple:
JSON est la manière d'aller, comme mentionné par d'autres, à mon humble avis
Note: je poste ce que de nouveaux réponse que je ne sais pas comment répondre directement (nouveau ici).
Ne pas utiliser PHP sérialisation/unserialization lorsque l'autre extrémité est pas de PHP. Il n'est pas destiné à être un format portable - par exemple, il inclut même ascii-1 caractères pour les clés protégées qui n'est rien que vous souhaitez traiter en javascript (même si elle fonctionne parfaitement bien, c'est juste très moche).
Au lieu de cela, utilisez un format portable comme JSON. XML pour faire le travail, aussi, mais JSON a moins de frais généraux et plus de programmeurs que vous pouvez facilement analyser en une simple structure de données au lieu d'avoir à traiter avec XPath, DOM arbres etc.
Encore une légère variation, ici, qui nous l'espérons aider quelqu'un ... j'ai été la sérialisation d'un tableau puis de les écrire sur une base de données. Sur la récupération des données de la unserialize opération a été un échec.
Il s'avère que la base de données longtext domaine que j'écrivais, c'était à l'aide de latin1 pas en UTF8. Quand je l'ai mis rond, tout a fonctionné comme prévu.
Merci à tous les ci-dessus qui ont mentionné l'encodage des caractères et m'a mis sur la bonne voie!
Je vous conseille d'utiliser le javascript pour encoder en json et ensuite utiliser la fonction json_decode à unserialize.
, nous pouvons briser la chaîne à un tableau:
Sérialiser:
Unserialize:
ce a travaillé pour moi.
Dans mon cas, le problème était avec les fins de ligne (probablement quelques éditeur ont changé mon fichier DOS vers Unix).
J'ai mis en place ces apadtive wrappers: