【问题标题】:Is it possible to instantiate as child object but then extract the parent object in PHP?是否可以实例化为子对象,然后在 PHP 中提取父对象?
【发布时间】:2016-05-22 21:26:31
【问题描述】:

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

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

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

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

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


编辑:我发现了以下问题,其选择的答案提出了一种 hackish 方式来重新转换序列化字符串,以便将其反序列化为不同的对象......

Convert/cast an stdClass object to another class

这可能有效,但在更下方看起来有人也在通过 Reflection 类执行此操作,这更接近我正在寻找的内容。除非有其他建议,否则我可能会试一试并报告回来?

【问题讨论】:

  • 对不起,我不认为你可以。要获取父对象,您需要实例化父类。但是,您应该可以通过使用“parent::example()”从子对象访问父方法和属性,例如调用父“示例”方法。
  • 对不起@CatalinCislariu,但很明显我可以访问父属性和方法......这就是我提出它的原因。就能够重新转换或提取父级而言,您是否可以参考任何导致您得出该结论的内容?
  • 我错了,看底部。
  • @CatalinCislariu 是的,我把它放在那里,这是我的问题?!​​?!无论如何,反射类解决方案奏效了,我已邀请该用户在这里回答。

标签: php zend-framework serialization parent-child extends


【解决方案1】:

我能够通过使用稍微不同的搜索标准找到另一个答案,该标准更多地处理 casting 而不是提取。最终为我工作的解决方案是基于我承认只有一点经验的反射类,原始答案在这里找到:

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,并允许我在其他地方使用这个方便的技巧。

希望有帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多