一尘不染

PHP反序列化失败,并出现非编码字符?

php

$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>";

但为什么?
我应该在序列化之前编码吗?怎么样?

我使用Javascript将序列化的字符串写入隐藏字段,而不是PHP的$ _POST
在JS中我有类似的东西:

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));
};

阅读 332

收藏
2020-05-29

共1个答案

一尘不染

unserialize()失败的原因:

$ser = 'a:2:{i:0;s:5:"héllö";i:1;s:5:"wörld";}';

是因为for的长度héllöwörld是错误的,因为PHP本身无法正确处理多字节字符串:

echo strlen('héllö'); // 7
echo strlen('wörld'); // 6

但是,如果您尝试unserialize()使用以下正确的字符串:

$ser = 'a:2:{i:0;s:7:"héllö";i:1;s:6:"wörld";}';

echo '<pre>';
print_r(unserialize($ser));
echo '</pre>';

有用:

Array
(
    [0] => héllö
    [1] => wörld
)

如果使用PHP,serialize()它应该正确计算多字节字符串索引的长度。

另一方面,如果要使用多种(编程)语言处理序列化数据,则应将其忘记,而转而使用JSON(JSON)之类的方法,该方法更加标准化。

2020-05-29