【问题标题】:PHP - how to check two references are pointing to the same underlying object (memory address)?PHP - 如何检查两个引用是否指向同一个底层对象(内存地址)?
【发布时间】:2020-01-10 19:28:31
【问题描述】:

我来自 Java 背景,对 PHP 有点陌生。

我想知道是否有一个 PHP 等效于 Java 的 "==" 操作,它基本上检查两个引用是否引用完全相同的底层对象。 (PHP 的 == 和 === 更像 Java 的 equals 方法,检查两个底层对象是否具有相同的值)

澄清: 我的问题不在于 PHP 中 == 和 === 之间的区别,也不在于如何比较 PHP 中的值。我正在寻找一种方法来查看 2 个变量是否指的是同一个对象/内存地址。相同的对象/内存地址意味着当我更新变量 $a 时,$b 也需要更新,反之亦然,因为 $a 和 $b 指的是同一个东西。

【问题讨论】:

标签: java php object reference memory-address


【解决方案1】:

=== 只显示两个变量是否具有相同的类型和值,但不能显示两个变量是否指向相同的地址。

无论两个变量是否指向同一个地址,php 都不会暴露这个。

但是你可以通过一些解决方法来解决它。

方式 1. 使用调试信息获取它,例如 var_dumpdebug_zval_dump()

方式2.修改变量$a,查看$b是否也被修改。

【讨论】:

  • 这是不正确,检查PHP Comparing Objects:当使用恒等运算符(===)时,对象变量是相同的当且仅当它们引用同一个类的同一个实例。
  • 同一个类的同一个实例不等于同一个地址。
【解决方案2】:

在使用比较运算符(==)时,每个对象的变量比较简单,即:一个对象的两个实例如果属性和值相同则相等(值用=比较=),它们是同一个类的实例。

当使用恒等运算符 (===) 时,对象的变量是相同的,是的,并且仅当它们引用同一类的相同实例时。

【讨论】:

  • 比较运算符只查看值和数据类型。 3v4l.org/mtVkU 所以if they refer to the same instance of the same class 不正确。
  • 我想你误解了我的问题。我想看看 2 个变量是否指的是同一个对象/内存地址。它们具有相同的值并不意味着它们是相同的对象。例如,当您更改 A 时,B 也需要更改,因为 A 和 B 指的是同一个东西。
  • @user3783243 您在与官方 PHP 文档相矛盾吗?您的示例仅表明 PHP 始终执行类似于 Java 中的 String.intern() 的操作 - 具有相同值的字符串指向同一个对象。
  • @ErwinBolwidt 您指的是哪个文档?我指的是php.net/manual/en/language.operators.comparison.php,这就是这个答案所指的。你怎么说Strings with the same value point to the same object?我可以有两个具有相同值的不同对象。
  • php.net/manual/en/language.oop5.object-comparison.php "当使用恒等运算符 (===) 时,当且仅当它们引用同一个类的同一个实例时,对象变量是相同的。 - 如果我理解正确,OP 正在谈论对象。
【解决方案3】:

serialize 函数可以被滥用来检查两个变量是否相同。

<?php

// check if two variables are the same reference
function same(&$a, &$b) {
  // serialize an array containing only the two arguments
  // check if the serialized representation ends with a reference.
  return substr(serialize([&$a, &$b]), -5) === 'R:2;}';
}

$a = 4;
$b = &$a;
$c = 4;

echo "same(\$a, \$b) === " . var_export(same($a, $b), true) . "\n";
echo "same(\$a, \$c) === " . var_export(same($a, $c), true) . "\n";
echo "same(\$b, \$c) === " . var_export(same($b, $c), true) . "\n";

// same($a, $b) === true
// same($a, $c) === false
// same($b, $c) === false

?>

警告:

  • __serialize() 或 __sleep() 之类的魔术方法可能会导致副作用。
  • 如果您的变量是大型对象,性能可能会受到影响。
  • 如果 PHP 在新版本中更改序列化输出,此函数可能会中断。

【讨论】:

    猜你喜欢
    • 2017-01-20
    • 2011-11-11
    • 1970-01-01
    • 2023-04-03
    • 2021-02-26
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    相关资源
    最近更新 更多