oop — PHP: проверить, является ли объект клоном (любого объекта) или нет?

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));

На самом деле мой вопрос: «Как обнаружить объект, который клонирует некоторый объект».

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
2

Другие решения

как насчет этого

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;
}
}
1

Другой вариант:

function isCloneOf($object) {
return empty(array_diff((array)$object, (array)$this));
}
0
По вопросам рекламы [email protected]