我正在使用 PHP 5.2。我想找到一种方法为每个对象输出一个唯一的 id,因此在查看日志以查看哪些对象相同时很容易。
在 Ruby 中,我只想说 object.object_id 来获取对象的 Ruby 内部标识符。在 PHP 中似乎没有明显的方法可以做到这一点。
有内置的方法吗?如果没有,您能提供其他建议吗?
从版本 5.3.6 开始,目前在 PHP 中没有办法做到这一点。
spl_object_hash() 不会做你想做的事 - 因为它会在对象被删除时回收标识符,这将导致(例如)对象关系映射器尝试跟踪会话中的对象时出错。
文档页面顶部的描述(“此函数返回对象的唯一标识符。此 id 可用作存储对象或识别对象的哈希键。”)是错误的 - 真相在该页面上的注释:“当一个对象被销毁时,它的哈希可能会被其他对象重用”,或者换句话说,该函数并不总是返回唯一标识符,并且不能总是用于存储或识别对象。
此评论中演示的技术在某些情况下可能有效,但它不可靠并且也不会始终如一地工作,因为尝试访问未定义的属性将调用 __get() 和 __set() 魔术方法,其结果是不可预测的。
总之,对您的问题的简短回答(不幸的是)是“否”——PHP 中没有这样的方法,也没有办法编写这样的方法来始终如一地适用于任何对象。
如果您希望将此功能添加到 PHP 中,请在此处投票和/或评论:
$test = (object)[];
var_dump(spl_object_id($test)); # int(1)
警告购买者(?):
当一个对象被销毁时,它的 id 可能会被其他对象重用。
我知道这是个老话题,但我想我已经找到了解决方案。
诀窍在于使用分配的键将每个对象的引用存储在数组中。然后,您可以通过搜索该数组并返回找到的键来获取对象 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
*/