在 php 中,当涉及对象代理时,我如何确定相等性



在我的php应用程序中,我一直在将对象与通常的相等比较运算符进行比较,例如:

if ($objectA == $objectB) { ... }

最近我实现了代理(用于加载成本高昂的对象(,但这意味着相等运算符不再有效。 有没有一个简单的方法可以解决这个问题? 一个不依赖反思的人?

目前,我已经求助于测试每个对象的唯一标识符,例如

if ($objectA->getId() == $objectB->getId) { ... }

但这有两个问题:1(我需要重构所有现有代码,2(将来我可能需要比较作为值对象(而不是实体(的对象。

我对一个简单的解决方案不抱希望,因为我认为这需要一种新的神奇方法......

这是我的AbstractProxy类。 任何帮助感谢...

abstract class KOOP_Base_AbstractProxy
    implements KOOP_Base_iDomain
{
    use KOOP_Trait_Helper_Helper;
    /**
     * @var integer Object identifier
     */
    protected $_id = null;
    /**
     * @var KOOP_Base_AbstractMapper
     */
    protected $_mapper = null;
    /**
     * @var KOOP_Base_AbstractDomain Actual object
     */
    protected $_subject = null;
    /**
     * Store object id for lazy loading
     *
     * @param integer   $id Object identifier
     * @param string    $mapper Mapper by which to retrieve object
     */
    public function __construct($id, $mapper)
    {
        $this->_id = $id;
        $this->_mapper = $mapper;
    }
    /**
     * Get subject
     *
     * @return KOOP_Base_AbstractDomain
     */
    protected function getSubject()
    {
        if (!$this->_subject) {
            $this->_subject = $this->getMapper($this->_mapper)->find($this->_id);
        }
        return $this->_subject;
    }
    /**
     * Get property
     *
     * @param string $property
     * @return mixed
     */
    public function __get($property)
    {
        return $this->getSubject()->$property;
    }
    /**
     * Set property
     *
     * @param string $property
     * @param mixed $value
     * @return void
     */
    public function __set($property, $value)
    {
        $this->getSubject()->$property = $value;
    }
    /**
     * Is property set?
     *
     * @param $property
     * @return boolean
     */
    public function __isset($property)
    {
        return isset($this->getSubject()->$property);
    }
    /**
     * Unset property
     *
     * @param string $property
     * @return mixed
     */
    public function __unset($property)
    {
        unset($this->getSubject()->$property);
    }
    /**
     * Call method
     *
     * @param   string $method Method to call
     * @param   array  $params Parameters to pass
     * @return  mixed
     */
    public function __call($method, array $params)
    {
        return call_user_func_array(array($this->getSubject(), $method), $params);
    }
    /**
     * Get id
     *
     * Saves having to retrieve the entire object when only the ID is required.
     */
    public function getId()
    {
        return $this->_id;
    }
}

代理确实会破坏对象相等性,并且没有完全干净的方法来解决这个问题。在完全面向对象的语言中,您可以通过运算符重载(我不推荐(或实现自定义 .equals(( 函数(如在 Java 中(来处理这个问题。可悲的是,PHP根本不支持此级别的面向对象,因此您将需要做出一些决定。

1(我希望你的代理类提供一个equals((函数,该函数将对要测试的对象的引用作为输入,并将其与代理对象进行比较 - 这不应该比根本不使用代理更"昂贵"。伪PHP代码中的示例(如果我的引用语法关闭,我深表歉意,已经有一段时间了(:

public function equals (&$toCompare)
{
 if ($_subject == $toCompare)
 {
    return true;
 }
 else
 {
    return false;
 }
}

缺点很简单:您必须重构涉及此代理对象的代码,并且您必须记住,"=="在您工作时不适用于此代理对象类型。如果你不怎么处理这些对象,或者如果你一直处理它们,这很好。如果您定期但间歇性地处理它们,或者其他人有时必须与他们合作,那么当您/他们忘记这个平等问题时,这将导致错误。

2( 对语言使用运算符重载扩展。我没有这样做,我不知道它是否有效,这可能是一场噩梦。为了理论完整性,我把它包括在内。

就个人而言,我想我会用伪 Java 方法破解它,因为我认为它实际上可以工作,只需要正确使用该函数(并记住首先使用它(。

最新更新