簡體   English   中英

PHP - 如何檢查兩個引用是否指向相同的底層 object(內存地址)?

[英]PHP - how to check two references are pointing to the same underlying object (memory address)?

我來自 Java,對 PHP 有點陌生。

我想知道是否有一個 PHP 等同於 Java 的“==”操作,它基本上檢查兩個引用是否引用完全相同的底層 object。(PHP 的 == 和 === 更像 Java 的 equals 方法,它檢查是否兩個底層對象具有相同的值)

澄清:我的問題不是關於 PHP 中 == 和 === 之間的差異,也不是關於如何比較 PHP 中的值。我正在尋找一種方法來查看 2 個變量是否引用相同的對象/內存地址。 相同的對象/內存地址意味着當我更新變量 $a 時,$b 也需要更新,反之亦然,因為 $a 和 $b 指的是同一事物。

===僅顯示兩個變量是否具有相同的類型和值,但無法顯示兩個變量是否指向相同的地址。

無論兩個變量是否指向相同的地址,php 都不會公開這一點。

但是您可以通過一些解決方法來獲得它。

方式 1. 使用調試信息獲取它,例如var_dumpdebug_zval_dump()

方式2.修改變量$a ,並檢查$ b 是否也被修改。

使用比較運算符(==)時,比較每個對象的變量的方式比較簡單,即:一個對象的兩個實例如果屬性和值相同,則它們相等(值用==進行比較),它們是同一個類的實例。

當使用身份運算符 (===) 時,對象的變量是相同的,並且僅當它們引用同一類的同一實例時。

這里的其他答案似乎缺少檢查 object 的兩個實例在 memory 中是否相同的具體要求。 這與檢查兩個類是否具有相同的屬性不同!

PHP 的對象===運算符僅在兩個對象共享相同的 memory 地址時才返回 true。 這不適用於其他原始類型( stringsfloats等),它們可以具有相同的類型和值,但具有唯一的 memory 地址。

PHP 在請求生命周期中為每個唯一的 object 提供一個 integer ID:如果兩個類公開具有不同名稱但相同 object ID 的屬性,修改一個 class 中的屬性將導致它在另一個中被修改。

可以使用spl_object_id()來唯一標識 memory 中的對象:

$users = Database::getAllUsers()->mapRowsToObjects();

$people = new People($users->all());
$heroes = new Heroes($users->withSuperPowers());

$superMan  = $heroes->withAlias('Superman')->first();
$clarkKent = $people->named('Clark Kent')->first();


$superMan->location  = 'Krypton';
$clarkKent->location = 'Metropolis';

echo spl_object_id($superman);  // 4207
echo spl_object_id($clarkKent); // 4207
var_export($superman === $clarkKent); // true

// Because these objects share the same ID, changing one affects them both:
echo $superMan->location; // 'Metropolis'

可以濫用序列化函數來檢查兩個變量是否相同。

<?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 在新版本中更改了序列化輸出,則此功能可能會中斷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM