我在这里试用了answer of Tom Haigh,但发现了两个问题。 1.当您将其他“Incomplete_Class”对象作为顶级类的属性时,它们将保持不变,即__PHP_Incomplete_Class Object 1.如果你有私有属性,它们在你的stdClass对象中仍然是私有的 所以我重写了函数句柄:
/**
* @see: https://stackoverflow.com/a/965704/2377961
*
* @param object $object The object that should be casted
* @param String $class The name of the class
* @return mixed The new created object
*/
function casttoclass($object, $class = 'stdClass')
{
$ser_data = serialize($object);
# preg_match_all('/O:\d+:"([^"]++)"/', $ser_data, $matches); // find all classes
/*
* make private and protected properties public
* privates is stored as "s:14:\0class_name\0property_name")
* protected is stored as "s:14:\0*\0property_name")
*/
$ser_data = preg_replace_callback('/s:\d+:"\0([^\0]+)\0([^"]+)"/',
function($prop_match) {
list($old, $classname, $propname) = $prop_match;
return 's:'.strlen($propname) . ':"' . $propname . '"';
}, $ser_data);
// replace object-names
$ser_data = preg_replace('/O:\d+:"[^"]++"/', 'O:' . strlen($class) . ':"' . $class . '"', $ser_data);
return unserialize($ser_data);
}
8条答案
按热度按时间kx7yvsdv1#
当你反序列化一个还没有包含的类的对象时,这个问题就会出现。例如,如果你在包含这个类之前调用session_start。
不能直接访问PHPIncompleteClass对象,但可以使用foreach,serialize和gettype.使用PHPIncompleteClass对象调用is_object将导致false.
因此,如果您在会话中发现了一个'__PHP_Incomplete_Class'对象,并且在session_load之后包含了您的类,则可以使用以下函数:
这将产生一个可用的对象:
smdncfj32#
我发现这个黑客可以让你投一个对象:
从http://blog.adaniels.nl/articles/a-dark-corner-of-php-class-casting/开始
所以你可以:
然后照常访问属性。
你也可以在一个. htaccess/Apache配置文件中定义一个
unserialize_callback_func
,这样你就不需要破解任何PHP,但是你可以根据需要包含这个文件。0sgqnhkj3#
下面是我的fix_object()函数版本:主要更改是代码中的步骤3:公开所有属性。
当PHP序列化一个对象时,所有私有和受保护的属性都以两个空字节作为前缀!这些空字节是真正的原因,为什么不能通过
$obj->key
访问该属性,因为实际上它类似于$obj->{NULL*NULL}key
。var_dump
不会向您显示这些NULL字节前缀,但您可以通过以下代码看到它们:你看:
NULL + classname + NULL
NULL + "*" + NULL
vbkedwbf4#
上面的答案没有一个对我有效,除了这个解决方案:
$object =反序列化(序列化($object));
$对象-〉函数();
希望能帮到什么人
fkaflof65#
我在这里试用了answer of Tom Haigh,但发现了两个问题。
1.当您将其他“Incomplete_Class”对象作为顶级类的属性时,它们将保持不变,即
__PHP_Incomplete_Class Object
1.如果你有私有属性,它们在你的
stdClass
对象中仍然是私有的所以我重写了函数句柄:
我也切换了函数参数,这样您就可以使用
你得到一个只有公共属性的
stdClass
对象,即使你在子类中有对象,它们也会被转换成有公共属性的stdClass
。fsi0uk1n6#
如果你只需要访问PHP_Incomplete_Class对象中的原始数据(比如类变量),你可以使用foreach hack,或者你也可以:
bf1o4zei7#
将require之后的session_start()放到您试图从SESSION读取的对象的类中
u0sqgete8#
我读了很多关于如何修复不完整类对象的建议,实际上我需要自己修复这些问题,在一个电子商务项目中。
我发现的一个建议是简单地使用json_decode/json_encode来转换不完整的类,而不需要预加载任何东西。然而,我不想冒险使用这个,如果有旧的PHP版本依赖于例如PECL,这在http://php.net/manual/en/function.json-encode.php中有描述-所以我最终成功地制作了我自己的解决方案。
然而,代码是一种从对象中正确获取数据的方法,因此它可能无法满足所有需求--而且它将首先使用json-solution(如果环境中有可用的话),然后在需要时故障转移到手动处理。
它还可以递归地工作,这在我自己的情况下是必需的,以保存整个数组。