是否可以实例化为子对象,然后在 PHP 中提取父对象


Is it possible to instantiate as child object but then extract the parent object in PHP?

我在解决Zend Framework 1.x中的限制时遇到了问题,目前无法替换或更新它。 我有一个新颖的想法,但我不确定它是否可能。

基本问题是是否可以实例化扩展子对象,然后提取父对象进行序列化?

为了说明原因,本质上Zend_Mail类对其方法有一些非常愚蠢的限制和类型检查,在我的例子中特别$mail->setType().

我的想法是我可以创建一个扩展类(My_Zend_Mail extends Zend_Mail(,然后覆盖我的类中的setType() {...}方法,消除限制,允许我在Zend_Mail类中设置某些protected属性。 限制是我需要将其作为序列化对象传递给远程服务器,并且该远程服务器在未序列化时不会具有或识别My_Zend_Mail类。 所以我只需要序列化我最后的Zend_Mail父级。

所以回到最初的问题,我可以在通过扩展子对象实例化父对象之后提取它吗?


编辑:我发现了以下问题,其所选答案提出了一种黑客方法来重新转换序列化字符串,以便它作为不同的对象取消序列化......

将 stdClass 对象转换/强制转换为另一个类

这可能会起作用,尽管再往下看,似乎有人也在通过反射类执行此操作,这更接近我正在寻找的内容。 我可能会试一试并报告,除非有其他建议?

我能够通过使用稍微不同的搜索条件来找到另一个答案,这些搜索条件更多地处理了强制转换而不是提取。 最终对我有用的解决方案是基于反射类,我承认只有一点经验,原始答案在这里找到:

https://stackoverflow.com/a/9812059/1058733

我在这里为后代复制代码,但这是直接复制的......

/**
 * Class casting
 *
 * @param string|object $destination
 * @param object $sourceObject
 * @return object
 */
function cast($destination, $sourceObject)
{
    if (is_string($destination)) {
        $destination = new $destination();
    }
    $sourceReflection = new ReflectionObject($sourceObject);
    $destinationReflection = new ReflectionObject($destination);
    $sourceProperties = $sourceReflection->getProperties();
    foreach ($sourceProperties as $sourceProperty) {
        $sourceProperty->setAccessible(true);
        $name = $sourceProperty->getName();
        $value = $sourceProperty->getValue($sourceObject);
        if ($destinationReflection->hasProperty($name)) {
            $propDest = $destinationReflection->getProperty($name);
            $propDest->setAccessible(true);
            $propDest->setValue($destination,$value);
        } else {
            $destination->$name = $value;
        }
    }
    return $destination;
}

示例用法是这样说明的...

class A {
  private $_x;   
}
class B {
  public $_x;   
}
$a = new A();
$b = new B();
$x = cast('A',$b);
$x = cast('B',$a);

因此,最终反射类使我们能够访问Zend_Mail内受保护的参数,而无需扩展它。 我本可以重写该方法以跳过我们确实扩展原始类以设置值的步骤,然后使用此方法对其进行转换,但是保持这样更OO并允许我在其他地方使用这个方便的技巧。

希望对您有所帮助!