2012-09-18 161 views
1

我们有一个抛出错误的错误处理程序: __PHP_Incomplete_Class无法转换为字符串。如何从不完整的课程中获取课程名称?

错误处理程序当前执行'is_object'测试,对于'Incomplete'对象奇怪地是错误的。我试图调整错误处理程序,但我无法获取原始类名称,而无需解析重新序列化的版本。

<?php 

$o = 'O:14:"BogusTestClass":0:{}'; 

$c = unserialize($o); 

var_dump(
    array(
     'subject' => $c, 
     'is_object' => is_object($c), // false !?!? 
     'get_class' => get_class($c), // __PHP_Incomplete_Class 
     'gettype' => gettype($c),  // 'object' 
     'Is instance of?' => $c instanceof __PHP_Incomplete_Class, // true 
     'serial' => serialize($c), 
    ) 
);  

// Tried: 

var_dump($c->__PHP_Incomplete_Class_Name); 
// Error: 
// The script tried to execute a method or access a property of 
// an incomplete object 


$refObj = new ReflectionObject($c); 
$refProp = $refObj->getProperty('__PHP_Incomplete_Class_Name'); 
$refProp->setAccessible(true); 
var_dump($refProp->getValue($c)); 
// Error: 
// ReflectionProperty::getValue(): The script tried to execute a 
// method or access a property of an incomplete object. 


// This works, but is fragile, since it depends on internal behavior 
// of serialize 
function getBadClassName($subject) 
{ 
    $serial = serialize($subject); 
    $parts = explode(':', $serial, 4); 

    if ('O' === $parts[0] && strlen($parts[2]) -2 == $parts[1]) { 
     return substr($parts[2], 1, -1); 
    } 
    return '-- Error --'; 
} 

var_dump(getBadClassName($c)); 

试图从不完整的对象中获取序列化类的名称以用于错误消息。

避免解析字符串,因为我猜测字符串解析会在使用重定义序列化/反序列化的扩展时崩溃,如http://pecl.php.net/package/igbinaryhttp://pecl.php.net/package/APC/3.1.7 apc.serializer挂钩。

+2

错误被抛出一个错误?你除以零不是吗?你不是吗?! –

+0

从Symfony2的FlattenException引发错误,并且如果为不完整的对象添加一点点,将会很微不足道,但如果可能的话,想添加缺少的名称。 – rrehbein

回答

0

你真的不能使用PHP不完整的类对象,并且它对我来说很有意义,因为它们不能用作对象,因为你真的不能使用它们。他们存在的唯一原因是他们可以坚持在不需要他们的页面上的会话。

如果你真的需要它,你必须包括对象系列化之前类的定义(如果它在会议上,session_start之前)。错误消息甚至说这个。基于一个建议

+1

在大多数情况下,您的正确之处仅仅是修复自动加载程序或包含缺失类的问题。然而,在遇到这种情况时,错误是由一个重构的类从缓存中退出,而不是自动加载失败触发的。当然,修复的方法是刷新缓存,但同时,由于部署,我们在实时系统上发生了错误,但由于错误处理程序中触发了错误,所以错误消息很少有线索。问题是关于修复错误处理程序,而不是丢失的类。 – rrehbein