gpt4 book ai didi

PHP反序列化没有匹配类的对象

转载 作者:可可西里 更新时间:2023-11-01 00:46:28 24 4
gpt4 key购买 nike

我有包含序列化对象的数据库行。

我想反序列化这些,但类已更改,一些属性变为私有(private),因此反序列化不再有效。

有没有办法强制反序列化为数组或标准类? (或反序列化时不会导致错误的任何东西)

我想避免使用脚本迁移数据。我宁愿向后兼容以旧格式序列化的对象。

最佳答案

不是真的,或者至少我会很害怕在生产中使用这样的东西。但是,unserialize 将使用自动加载系统或 unserialize_callback_func ini 设置中指定的函数名称。因此,通过一些黑客攻击,您可以完成这项工作:

// this a serialized object with the class "SomeMissingClass"
$str = 'O:16:"SomeMissingClass":1:{s:1:"a";s:1:"b";}';
ini_set('unserialize_callback_func', 'define_me'); // set your callback_function

// unserialize will pass in the desired class name
function define_me($classname) {
// just create a class that has some nice accessors to it
eval("class $classname extends ArrayObject {}");
}
$object = unserialize($str);
print $object['a']; // should print 'b'

您可以使用类似的方法将您的数据迁移到更方便的格式。

更新:

我在这方面咨询了我压抑的内存(我曾经遇到过这样的事情)并想起了另一个解决方案:

所以你的 SomeClass 有一个名为 $aprivate 属性

class SomeClass {
private $a;
public function getA(){
return $this->a;
}
}

你有它的序列化版本:

$str = 'O:9:"SomeClass":1:{s:1:"a";s:1:"b";}';

当你反序列化它并转储结果时,它看起来像这样,这是不好的:

$a = unserialize($str);
var_dump($a->getA()); // prints 'null'
var_dump($a);
/*
prints:
object(SomeClass)#1 (2) {
["a":"SomeClass":private]=>
NULL
["a"]=>
string(1) "b"
}
*/

现在,当一个对象被反序列化时,php 将调用它的 __wakeup 魔法方法。您需要的数据在对象中,但不在私有(private)属性下,而是在名称相似的公共(public)属性下。你不能用 $this->a 找到它,因为它会寻找错误的,然而方法get_object_vars()将返回这些属性,您可以在 __wakeup() 中重新分配它们:

class SomeClass {
private $a;
public function getA(){
return $this->a;
}
public function __wakeup(){
foreach (get_object_vars($this) as $k => $v) {
$this->{$k} = $v;
}
}
}
$str = 'O:9:"SomeClass":1:{s:1:"a";s:1:"b";}';
$a = unserialize($str);
print $a->getA();

我认为不用说,您应该避免进一步的头痛并将您的数据转换为某种专用的数据交换格式。

关于PHP反序列化没有匹配类的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17338057/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com