首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >PHP取消序列化失败,是否包含非编码字符?

PHP取消序列化失败,是否包含非编码字符?
EN

Stack Overflow用户
提问于 2010-05-18 06:52:21
回答 14查看 38.8K关注 0票数 32
代码语言:javascript
运行
复制
$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中,我有一些类似的东西:

代码语言:javascript
运行
复制
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));
};
EN

回答 14

Stack Overflow用户

回答已采纳

发布于 2010-05-18 07:33:42

unserialize()失败的原因是:

代码语言:javascript
运行
复制
$ser = 'a:2:{i:0;s:5:"héllö";i:1;s:5:"wörld";}';

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

代码语言:javascript
运行
复制
echo strlen('héllö'); // 7
echo strlen('wörld'); // 6

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

代码语言:javascript
运行
复制
$ser = 'a:2:{i:0;s:7:"héllö";i:1;s:6:"wörld";}';

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

它是有效的:

代码语言:javascript
运行
复制
Array
(
    [0] => héllö
    [1] => wörld
)

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

另一方面,如果你想用多种(编程)语言处理序列化的数据,你应该忘掉它,转向像JSON这样更标准化的东西。

票数 56
EN

Stack Overflow用户

发布于 2011-04-28 10:50:50

我知道这是一年前发布的,但我只是遇到了这个问题,实际上我找到了一个解决方案。这段代码工作起来很有魅力!

背后的想法很简单。它只是通过重新计算@Alix上面发布的多字节字符串的长度来帮助你。

一些修改应该适合您的代码:

代码语言:javascript
运行
复制
/**
 * Mulit-byte Unserialize
 *
 * UTF-8 will screw up a serialized string
 *
 * @access private
 * @param string
 * @return string
 */
function mb_unserialize($string) {
    $string = preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $string);
    return unserialize($string);
}

来源:http://snippets.dzone.com/posts/show/6592

在我的机器上测试过,它的效果很好!!

票数 52
EN

Stack Overflow用户

发布于 2015-01-13 22:30:20

修改后的Lionel Chan答案可与PHP >= 5.5一起使用:

代码语言:javascript
运行
复制
function mb_unserialize($string) {
    $string2 = preg_replace_callback(
        '!s:(\d+):"(.*?)";!s',
        function($m){
            $len = strlen($m[2]);
            $result = "s:$len:\"{$m[2]}\";";
            return $result;

        },
        $string);
    return unserialize($string2);
}    

从PHP5.5开始,这段代码使用preg_replace_callback作为 with the /e modifier is obsolete

票数 32
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2853454

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档