Предположим, что у нас есть следующее:
class Foo
{
public static $foo;
public static $bar;
public static $baz;
public static $str;
public static $arr;
}
class Bar
{
public static $foo;
public static $bar;
public static $baz;
public static $str;
public static $arr;
}
class Baz
{
public static $foo;
public static $bar;
public static $baz;
public static $str;
public static $arr;
}
Foo::$foo = new Foo();
Bar::$foo = Foo::$foo;
Baz::$foo = Foo::$foo;
Foo::$bar = new Bar();
Bar::$bar = Foo::$bar;
Baz::$bar = Foo::$bar;
Foo::$baz = new Baz();
Bar::$baz = Foo::$baz;
Baz::$baz = Foo::$baz;
Foo::$str = 'cat';
Bar::$str = Foo::$str;
Baz::$str = Foo::$str;
Foo::$arr = [1, 2, 3, 'dog'];
Bar::$arr = Foo::$arr;
Baz::$arr = Foo::$arr;
ГДЕ: Foo::$foo
, Bar::$foo
, Baz::$foo
относится к одному экземпляру Foo
; Foo::$bar
, Bar::$bar
, Baz::$bar
относятся к одному экземпляру Bar
; Foo::$baz
, Bar::$baz
, Baz::$baz
ссылаются на один экземпляр Baz
; Foo::$str
, Bar::$str
, Baz::$str
ссылаются на одну строку; Foo::$arr
, Bar::$arr
, Baz::$arr
ссылаются на один массив;
Есть ли способ идентифицировать эти ценности? Например, в C++ я мог бы просто использовать указатель, который будет содержать одно и то же значение для Foo::$foo
, Bar::$foo
и Baz::$foo
.
Для чего это?
У меня есть функция, которая выполняет итерацию всех свойств заданных классов и записывает значения свойств в общий массив.
Предположим, что мы итерируем свойства Foo, Bar и Baz и добавляем их в массив. В конечном массиве у нас будет 15 значений вместо 5 (действительно разные значения). Если мы будем искать и сравнивать эти значения перед добавлением в массив, то (если "Foo :: $ str", "Bar :: $ str" и "BAZ :: $ str" не будут ссылаться на одно и то же значение, а равно равные значения), мы У меня есть только 5 значений вместо 7 (3 объекта, 1 массив и 3 строки).
Надеюсь, это редактирование поможет мне понять.
Также:
$a = 1;
$b = &$a;
$c = 1;
($a == $b) // true
($a == $c) // true
В обоих случаях результат будет правдой. Но как узнать, что im сравнивает 2 ссылки одного и того же значения (2 refs, что указывает тот же адрес памяти) или im сравнивает 2 разных адреса памяти, и они они равны? Это будет полезно для решения этой проблемы.
хорошо, я признаю, что не совсем понимаю, что вы пытаетесь сделать... но я возьму на него удар и предлагаю вам, чтобы суперкласс держал ваш статический $ foo, $ bar и т.д., тогда вы может простираться оттуда. здесь усеченный пример.
<?php
abstract class Super
{
static $foo;
static $bar;
}
class Foo extends Super
{
public function test() {
print "i am foo\n";
}
}
class Bar extends Super
{
public function test() {
print "i am bar\n";
}
}
$foo = new Foo();
Bar::$foo = $foo;
Bar::$foo->test(); // "i am foo""
$foo->test(); // "i am foo"
Когда я прочитал это, вы, похоже, пытаетесь определить, является ли данная ссылка уникальной или нет.
В PHP, когда вы создаете экземпляр объекта и назначаете его переменной (будь то стандартная переменная в области видимости или свойство object/class), вы назначаете ссылку, которая является псевдонимом таблицы символов, а не указателем.
Вы можете использовать строгое равенство ===
чтобы определить, являются ли значения одним и тем же экземпляром того же типа.
Итак, учитывая пример, аналогичный тому, который вы предоставили:
class Foo
{
}
class Bar
{
public static $bar;
}
$foo = new Foo();
Bar::$foo = $foo;
Оба $foo
и Bar::$foo
относятся к экземпляру Foo
который мы создали. Мы можем доказать это со строгим равенством:
var_dump($foo === Bar::$foo); // bool(true)
С другой стороны, следующее:
$foo = new Foo();
Bar::$foo = new Foo();
var_dump($foo === Bar::$foo); // bool(false)
Потому что сравниваемые экземпляры в этом случае различны.
Вы также можете использовать spl_object_hash()
который возвращает уникальный идентификатор хэша для объекта.
Пересмотр первого примера выше:
$foo = new Foo();
Bar::$foo = $foo;
var_dump(spl_object_hash($foo));
var_dump(spl_object_hash(Bar::$foo));
Урожайность:
string(32) "00000000706dad460000000129210cdf"
string(32) "00000000706dad460000000129210cdf"
Оба хэша объектов одинаковы для каждой ссылки; т.е.: тот же базовый объект.
Напротив, второй пример, когда мы создаем два новых экземпляра Foo
:
$foo = new Foo();
Bar::$foo = new Foo();
var_dump(spl_object_hash($foo));
var_dump(spl_object_hash(Bar::$foo));
Урожайность:
string(32) "0000000004e5dfeb0000000107143bbf"
string(32) "0000000004e5dfe80000000107143bbf"
Они выглядят почти одинаково, но если вы внимательно присмотритесь, это разные ценности.
Они не работают одинаково. В следующем примере:
Foo::$str = 'cat';
Bar::$str = Foo::$str;
Bar::$str = 'dog';
var_dump(Foo::$str, Bar::$str);
Урожайность:
string(3) "cat"
string(3) "dog"
Однако вы можете назначить скалярные значения по ссылке с помощью &
:
Foo::$str = 'cat';
Bar::$str = &Foo::$str;
Bar::$str = 'dog';
Это дает:
string(3) "dog"
string(3) "dog"
То же самое относится к массивам iirc.
Ваше обновление предполагает, что вы выполняете итерацию по объектам, чтобы поддерживать хранилище объектов или хранить уникальные ссылки. Я не уверен в вашем конкретном случае использования, но SplObjectStorage
может быть вам полезен.
Надеюсь это поможет :)