任何值的唯一ID(对象,数组,标量)

时间:2015-08-07 15:23:37

标签: php

让我们假设我们有以下内容:

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::$fooBar::$fooBaz::$foo引用Foo的相同实例;
Foo::$barBar::$barBaz::$bar引用Bar的相同实例;
Foo::$bazBar::$bazBaz::$baz引用Baz的相同实例;
Foo::$strBar::$strBaz::$str引用相同的字符串;
Foo::$arrBar::$arrBaz::$arr引用相同的数组;

有没有办法识别这些值?例如在C ++中我可以使用一个指针,该指针包含Foo::$fooBar::$fooBaz::$foo的相同值。
它的用途是什么? 我有一个函数,它迭代给定类的所有属性,并将属性值写入公共数组 让我们想象一下,我们正在迭代Foo,Bar和Baz的属性并将它们添加到数组中。在最终数组中,我们将有15个值而不是5个(真正不同的值)。如果我们在添加到数组之前搜索并比较这些值,那么(如果`Foo :: $ str,Bar :: $ str和BAZ :: $ str将不是refs为相同的值,而只是一个相等的值)我们只有5个值而不是7个(3个对象,1个数组和3个字符串) 我希望这个编辑有助于理解我。

此外:

$a = 1;  
$b = &$a;
$c = 1;

($a == $b) // true  
($a == $c) // true

在这两种情况下,结果都是正确的。但是如何知道我比较2个相同值的引用(2个引用指向相同的内存地址)或im比较2个不同的内存地址,它们只是相等?这对解决这个问题很有帮助。

2 个答案:

答案 0 :(得分: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"

答案 1 :(得分:0)

在我阅读时,您似乎在试图确定给定的引用是否唯一。

物件

在PHP中,当您实例化一个对象并将其分配给变量(无论是作用域中的标准变量,还是对象/类属性)时,您要分配一个reference,这是一个符号表别名,不是指针。

您可以使用严格相等===来确定值是否是相同类型的相同实例。

所以,给出一个与你提供的例子相似的例子:

class Foo
{
}

class Bar
{
    public static $bar;
}

$foo = new Foo();
Bar::$foo = $foo;

$fooBar::$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()返回对象的唯一哈希ID。

重新审视上面的第一个例子:

$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"

他们看起来几乎相同,但如果你仔细观察,它们就是不同的值。

阵列&amp;字符串

这些不以同样的方式工作。给出以下示例:

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可能对您有用。

希望这有帮助:)