2014-12-23 136 views
1
class Object {} 

$object = new Object(); 
$clone = clone $object; 

// no! 
printf("%d\n", $object == $clone); 
printf("%d\n", $object === $clone); 
// no! no no.. 
printf("%d\n", $object instanceof $clone); 
printf("%d\n", $clone instanceof $object); 
// cos, this is true 
printf("%d\n", $object instanceof $object); 
printf("%d\n", $clone instanceof $clone); 

// maybe something like this.. 
printf("%d\n", $clone cloneof $object); 
printf("%d\n", cloneof($clone, $object)); 

其實我的問題是,「如何檢測克隆某個對象的對象」。PHP:檢查對象是否是克隆(任何對象)?

回答

1

經過一番搜索,我什麼也沒找到。所以,要分享我的簡單的解決方案以及任何其他的答案/評論,歡迎..

class Object 
{ 
    private static $__hashes = []; 

    public function __clone() { 
     self::$__hashes[] = spl_object_hash($this); 
    } 

    public function isCloneOf($object) { 
     return ($this == $object && $this !== $object 
       && in_array(spl_object_hash($this), $object::$__hashes)); 
    } 
} 

$object = new Object(); 
$clone1 = clone $object; 
$clone2 = clone $object; 

printf("%d\n", $clone1->isCloneOf($object)); // 1 
printf("%d\n", $clone2->isCloneOf($object)); // 1 

printf("%d\n", $object->isCloneOf($object)); // 0 
printf("%d\n", $object->isCloneOf($clone1)); // 0 
printf("%d\n", $object->isCloneOf($clone2)); // 0 
printf("%d\n", $clone1->isCloneOf(new stdClass())); // 0 

$foo = $clone1; 
$bar =& $clone1; 
printf("%d\n", $foo->isCloneOf($object)); // 1 
printf("%d\n", $bar->isCloneOf($object)); // 1 

問題

// if I do this 
$clone1->a = 1; 
// then result will be false 
printf("%d\n", $clone1->isCloneOf($object)); // 0 
// if I do this (so must be same all vars in objects) 
$clone1->a = 1; 
$object->a = 1; 
printf("%d\n", $clone1->isCloneOf($object)); // 1 

// could not solve (giving up).. 
$clone1clone = clone $clone1; 
printf("%d\n", $clone1clone->isCloneOf($clone1)); // 1 
printf("%d\n", $clone1->isCloneOf($clone1clone)); // 1 
+0

在同一分鐘? – Rizier123

+0

*「經過一番搜索後,我什麼也沒找到。」* - 6分鐘前發佈了問題,之後立即給出答案。哇,很快的搜索;-) –

+0

當然不! :)我正在工作一段時間,並在看到「回答你的問題」的同時共享。 –

0

另一種選擇:

function isCloneOf($object) { 
    return empty(array_diff((array)$object, (array)$this)); 
} 
1

這個怎麼樣

class Object 
{ 
    private $id = null; 
    private $instance = null; 
    private $cloneOf = null; 

    public function __construct() 
    { 
     $this->id = uniqid(); 
     $this->instance = $this; 
    } 

    public function __clone() 
    { 
     $this->cloneOf = $this->instance; 
     $this->instance = $this; 
     $this->id = uniqid(); 
    } 

    public function isCloneOf($object) 
    { 
     if (!($object instanceof Object)) 
      return false; 
     $isClone = ($object->getId() === $this->cloneOf->getId()); 
     if ($isClone) 
      return true; 

     $cloneSource = $object->getCloneSource(); 
     if ($cloneSource) 
      return $this->isCloneOf($cloneSource); 

     return false; 
    } 

    public function getId() 
    { 
     return $this->id; 
    } 

    public function getCloneSource() 
    { 
     return $this->cloneOf; 
    } 
}