参数仅为简单字符串时的PHP取消序列化偏移错误

参数仅为简单字符串时的PHP取消序列化偏移错误,php,serialization,Php,Serialization,我在申请后问了一个问题 我正试图从数据库中获取的序列化字符串中取消序列化 我收到错误:取消序列化偏移错误 我有两个箱子 两种情况下的代码相同: $categories = preg_replace( '!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $data['Member']['category'] ); var_dump($categories); $cat_unserialize = unseria

我在申请后问了一个问题

我正试图从数据库中获取的序列化字符串中取消序列化

我收到错误:取消序列化偏移错误

我有两个箱子

两种情况下的代码相同:

 $categories = preg_replace( '!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'",  $data['Member']['category'] );        
 var_dump($categories);  
 $cat_unserialize = unserialize($categories);
 var_dump($cat_unserialize );  
案例1:何时

$data['Member']['category'] => Adventure Camps
string 'Adventure Camps' (length=15)

Notice (8): unserialize(): Error at offset 0 of 15 bytes

boolean false
$data['Member']['category'] => a:4:{i:0;s:9:"Adventure";i:1;s:12:"Sports ";i:2;s:15:"Training";i:3;s:29:"Educational";}
案例1:错误:

$data['Member']['category'] => Adventure Camps
string 'Adventure Camps' (length=15)

Notice (8): unserialize(): Error at offset 0 of 15 bytes

boolean false
$data['Member']['category'] => a:4:{i:0;s:9:"Adventure";i:1;s:12:"Sports ";i:2;s:15:"Training";i:3;s:29:"Educational";}
案例2:何时

$data['Member']['category'] => Adventure Camps
string 'Adventure Camps' (length=15)

Notice (8): unserialize(): Error at offset 0 of 15 bytes

boolean false
$data['Member']['category'] => a:4:{i:0;s:9:"Adventure";i:1;s:12:"Sports ";i:2;s:15:"Training";i:3;s:29:"Educational";}

案例2:无错误代码id正常工作

取消序列化仅适用于序列化字符串。在尝试取消序列化非序列化数组的字符串时,需要防止打印通知

$cat_unserialize = @unserialize($categories);
否则,我不知道为什么会有问题。
然后,在使用变量之前,可以检查它是数组还是字符串

if(is_array($cat_unserialize)) {
    //do something with array.
}
else {
    //do something with string.
}

另外,我不理解preg_replace()。为什么要删除使字符串序列化的元素,然后尝试取消序列化?

如果需要长选项:这是wordpress提供的

<?php
function is_serialized( $data ) {
    // if it isn't a string, it isn't serialized
    if ( !is_string( $data ) )
        return false;
    $data = trim( $data );
    if ( 'N;' == $data )
        return true;
    if ( !preg_match( '/^([adObis]):/', $data, $badions ) )
        return false;
    switch ( $badions[1] ) {
        case 'a' :
        case 'O' :
        case 's' :
            if ( preg_match( "/^{$badions[1]}:[0-9]+:.*[;}]\$/s", $data ) )
                return true;
            break;
        case 'b' :
        case 'i' :
        case 'd' :
            if ( preg_match( "/^{$badions[1]}:[0-9.E-]+;\$/", $data ) )
                return true;
            break;
    }
    return false;
}

在案例1中,您试图取消序列化未序列化的字符串-这就是问题所在?尝试“@unserialize”并将其与“false”进行比较,以检查其序列化代码在两种情况下是否相同。也许我不明白,但似乎您正在尝试
取消序列化
以前未序列化的内容<代码>冒险营地
未序列化。可能您的preg_replace函数在
案例1
方面出了问题?在阅读了更新的问题标题->之后,您不能对尚未序列化的字符串使用
取消序列化
。您必须序列化所有值(即使只有一个值而不是几个值),或者必须先检查它。
Adventure Camps
不是序列化字符串。这只是一根绳子。如果它是序列化的,那么它看起来更像是
s:15:“冒险营地”
使用
@
就像知道代码有问题,但不是解决问题,只是不给出一个***没有问题。除非信息存储不正确。在检索方面没有做错任何事。有了这些,你可以用:是的,答案看起来好多了。但我真的不明白这里的问题,或者他为什么这样做。比如在上面运行preg_replace()对我来说似乎很奇怪,所以可能一开始我误解了。