【问题标题】:How to get the class name out of an incomplete class?如何从不完整的类中获取类名?
【发布时间】:2012-09-18 15:11:04
【问题描述】:

我们有一个抛出错误的错误处理程序: __PHP_Incomplete_Class 无法转换为字符串。

错误处理程序当前执行“is_object”测试,奇怪的是,对于“不完整”对象,该测试为假。我正在尝试调整错误处理程序,但如果不解析重新序列化的版本,我无法获取原始类名。

<?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 hook。

【问题讨论】:

  • 错误是抛出错误?你除以零不是吗?你不是吗?!
  • Symfony2 的 FlattenException 抛出了错误,如果对象不完整,添加一些内容是微不足道的,但如果可能,希望添加缺少的名称。

标签: php


【解决方案1】:

根据建议查看

forcing access to __PHP_Incomplete_Class object properties

属性可以通过foreach和ArrayObject访问

<?php

$array = new \ArrayObject($object);
var_dump($array['__PHP_Incomplete_Class_Name']);

【讨论】:

    【解决方案2】:

    你真的不能使用 PHP 不完整的类对象,而且对我来说它们不算作对象是有道理的,因为你真的不能使用它们。它们存在的唯一原因是它们可以在不需要它们的页面上保持会话。

    如果您确实需要它,则必须在对象未序列化之前包含类的定义(如果它在会话中,则在session_start 之前)。错误消息甚至这么说。

    【讨论】:

    • 您说得对,在大多数情况下,这只是修复自动加载器或包含缺少的类的问题。但是,在我遇到的情况下,错误是由一个被重构的类从缓存中返回,而不是自动加载失败触发的。修复当然是刷新缓存,但与此同时,由于部署,我们的实时系统出现错误,但由于错误处理程序中触发的错误,错误消息几乎没有线索。问题是关于修复错误处理程序,而不是缺少的类。
    猜你喜欢
    • 2014-10-12
    • 2011-03-27
    • 1970-01-01
    • 2019-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    • 2014-06-04
    相关资源
    最近更新 更多