Уникальный идентификатор любого значения (объекты, массивы, скаляр)

1

Предположим, что у нас есть следующее:

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 разных адреса памяти, и они они равны? Это будет полезно для решения этой проблемы.

  • 0
    Если мое понимание классов верно, вы вызываете несвязанные свойства, также вы не можете вызывать свойства вне их класса, потому что они являются частными.
  • 0
    @ angelcool.net что ты имеешь ввиду?
Показать ещё 16 комментариев
Теги:

2 ответа

0

хорошо, я признаю, что не совсем понимаю, что вы пытаетесь сделать... но я возьму на него удар и предлагаю вам, чтобы суперкласс держал ваш статический $ 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"
0

Когда я прочитал это, вы, похоже, пытаетесь определить, является ли данная ссылка уникальной или нет.

Объекты

В 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 может быть вам полезен.

Надеюсь это поможет :)

  • 0
    я добавил это к вопросу, но это работает со скалярными типами? См. Пример $ a $ b $ c
  • 0
    Привет, извините - я понял, что забыл эту часть. Просто добавил более подробную информацию об этом.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню