52

我正在使用 PHP 5.2。我想找到一种方法为每个对象输出一个唯一的 id,因此在查看日志以查看哪些对象相同时很容易。

在 Ruby 中,我只想说 object.object_id 来获取对象的 Ruby 内部标识符。在 PHP 中似乎没有明显的方法可以做到这一点。

有内置的方法吗?如果没有,您能提供其他建议吗?

4

4 回答 4

84

为此使用spl_object_hash()

它为每个对象实例返回一个唯一标识符,而不是类的名称,因此它似乎更适合您。

编辑:

对于 PHP < 5.2.x 的用户,请参阅此答案

于 2008-11-21T07:46:58.100 回答
16

从版本 5.3.6 开始,目前在 PHP 中没有办法做到这一点。

spl_object_hash() 不会做你想做的事 - 因为它会在对象被删除时回收标识符,这将导致(例如)对象关系映射器尝试跟踪会话中的对象时出错。

文档页面顶部的描述(“此函数返回对象的唯一标识符。此 id 可用作存储对象或识别对象的哈希键。”)是错误的 - 真相在该页面上的注释:“当一个对象被销毁时,它的哈希可能会被其他对象重用”,或者换句话说,该函数并不总是返回唯一标识符,并且不能总是用于存储或识别对象。

此评论中演示的技术在某些情况下可能有效,但它不可靠并且也不会始终如一地工作,因为尝试访问未定义的属性将调用 __get() 和 __set() 魔术方法,其结果是不可预测的。

总之,对您的问题的简短回答(不幸的是)是“否”——PHP 中没有这样的方法,也没有办法编写这样的方法来始终如一地适用于任何对象。

如果您希望将此功能添加到 PHP 中,请在此处投票和/或评论:

http://bugs.php.net/bug.php?id=52657

于 2011-06-13T12:50:12.030 回答
6

⚠️ PHP 7.2.0 引入spl_object_id()

$test = (object)[];
var_dump(spl_object_id($test)); # int(1)
警告购买者(?)

当一个对象被销毁时,它的 id 可能会被其他对象重用。

于 2019-05-10T04:44:01.033 回答
0

我知道这是个老话题,但我想我已经找到了解决方案。

诀窍在于使用分配的键将每个对象的引用存储在数组中。然后,您可以通过搜索该数组并返回找到的键来获取对象 ID。

<?php

class objectMarker
{
    private $storage;

    function add($object) {
        $this->storage[] = $object;
    }

    function getId($object) {
        foreach ($this->storage as $id => $item) {
            if ($item === $object) {
                return $id;
            }
        }

        return null;
    }
}

$marker = new objectMarker;

$t1 = new stdClass;
$t2 = new stdClass;

$marker->add($t1);
$marker->add($t2);

echo $marker->getId($t1) . "\n";
echo $marker->getId($t2) . "\n";

unset($t1);

$t1 = new stdClass;
$marker->add($t1);

echo $marker->getId($t1) . "\n";

$t2->x = 1;
echo $marker->getId($t2) . "\n";

/* output:
0
1
2
1
*/
于 2016-01-04T21:06:23.077 回答