【问题标题】:problem in unserializing string in php 7.2在 php 7.2 中反序列化字符串的问题
【发布时间】:2019-01-27 07:58:51
【问题描述】:

当我在使用 php 5.6 之前取消序列化它不使用 php 7.2 时,我已经序列化了一个图像路径并保存到数据库。

a:1:{i:0;a:3:{s:8:"fullpath";s:77:"https://www.educationfolder.com/files1/user-pics/4/142944540636159131_ml.jpg";s:5:"image";s:27:"4/142944540636159131_ml.jpg";s:10:"mention_id";s:3:"398";}}


function made for this are 
function maybe_serialize( $data ) {
if ( is_array( $data ) || is_object( $data ) )
    return serialize( $data );
// Double serialization is required for backward compatibility.
// See http://core.trac.wordpress.org/ticket/12930
if ( is_serialized( $data, false ) )
    return serialize( $data );
return $data;
}

function maybe_unserialize( $original ) {
if ( is_serialized( $original ) ) // don't attempt to unserialize data that wasn't serialized going in
    return @unserialize( $original );
return $original;
}

现在我正在这样做

$imageArr = array();

$imageArr = maybe_unserialize(trim($image_url));

它不工作

【问题讨论】:

  • “不工作”是什么意思?
  • 我意识到我们已经将“上传”替换为“files1”,这就是为什么图像字符数在序列化字符串中为 77,但实际字符为 76,这需要修复以删除减号中的 1 个值那里
  • 你的数据库列是二进制类型吗?您不能将serialize() 的输出存储在例如VARCHAR.

标签: php serialization


【解决方案1】:

我已经在函数中使用快速修复解决了这个问题,这个错误是由于更改了序列化数据长度。

$data = preg_replace_callback('!s:(\d+):"(.*?)";!', function($m) { return 's:'.mb_strlen($m[2]).':"'.$m[2].'";'; }, $data);

function maybe_unserialize( $original ) {
if ( is_serialized($original) ) // don't attempt to unserialize data that wasn't serialized going in

$original = preg_replace_callback('!s:(\d+):"(.*?)";!', function($m) { return 's:'.mb_strlen($m[2]).':"'.$m[2].'";'; }, $original);
    return @unserialize($original);
return $original;

}

【讨论】:

    【解决方案2】:

    您是否手动编辑了序列化字符串?图片网址是 76 个字符,但在您的序列化字符串中显示为 77。

    $img = 'a:1:{i:0;a:3:{s:8:"fullpath";s:76:"https://www.educationfolder.com/files1/user-pics/4/142944540636159131_ml.jpg";s:5:"image";s:27:"4/142944540636159131_ml.jpg";s:10:"mention_id";s:3:"398";}}';
    
    $img = maybe_unserialize($img);
    
    echo $img[0]['fullpath'];
    

    顺便说一下,这些是 WordPress Core 的功能。 unserialize 之前的 @ 会抑制警告。您可以直接使用 unserialize() 而不使用带有原始序列化字符串的 @ 并获取:

    Notice: unserialize(): Error at offset 112 of 190 bytes
    

    3v4l 示例:

    https://3v4l.org/3NWlD

    【讨论】:

    • 我明白你的意思是我们已经将序列化数据“uploads”目录替换为“files1”,我可以通过任何方式更正整个表的值
    • 但是您是否手动更改了数据库?您不能在不重新计算长度的情况下更改序列化字符串。恢复您的数据库备份,获取您要编辑的所有记录,然后为每条记录反序列化字符串,对其进行编辑,再次对其进行序列化,最后更新数据库中的记录。
    • 是的,我在 mysql 中使用查询更改了数据并修复了这个重新计算的字符串
    【解决方案3】:

    如果你经常使用正则表达式,可以使用T-Regx tool

    pattern('s:(\d+):"(.*?)";')->replace($original)->callback(function(Match $m) { 
        return 's:' . $m->group(2)->length() . ':"' . $m->group(2) . '";'; 
    });
    

    它有自动分隔符。

    【讨论】:

      猜你喜欢
      • 2017-11-19
      • 1970-01-01
      • 2015-11-26
      • 2020-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多