简体   繁体   中英

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

I am from Java background and sort of new to PHP.

I am wondering whether there is a PHP equivalent to Java's "==" operation which basically checks whether two references are referring to the exact same underlying object. (PHP's == and === are more like Java's equals method, which is checking whether both underlying objects have the same value)

Clarification: My question is not about the differences between == and === in PHP nor how to compare values in PHP. I am looking for a way to see whether 2 variables are referring to the same object/memory address. The same object/memory address means that when I update variable $a, $b also needs to be updated and vice versa because $a and $b are referring to the same thing.

=== only show if the two variable have the same type and value, but cannot show if the two variable is point to the same address.

Php not expose this whether two variable point to the same address.

But you can get it with some workaround.

Way 1. get it with debug information, for example var_dump or debug_zval_dump() .

Way 2. modify variable $a , and check if $ b also is modified.

When using the comparison operator (==), the variables of each object are compared in a simple way, that is: two instances of an object are equal if they have the same attributes and values (the values are compared with ==), and they are instances of the same class.

When the identity operator (===) is used, the variables of an object are identical yes and only if they refer to the same instance of the same class.

Other answers here seem to be missing the specific requirement to check if two instances of an object are the same in memory . This is NOT the same thing as checking if two classes have identical properties!

PHP's === operator on objects will only return true when both objects share the same memory address. This doesn't apply to other primitive types ( strings , floats , etc.), which can have the same type and value, but have unique memory addresses.

PHP gives each unique object an integer ID during the request lifecycle: if two classes expose properties with different names but the same object ID, modifying the property in one class will cause it to be modified in the other.

You can use spl_object_id() to uniquely identify objects in 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'

The serialize function can be abused to check if two variables are the same.

<?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

?>

Warning:

  • Magic methods like __serialize() or __sleep() can cause side effects.
  • Performance may suffer if your variables are large objects.
  • If PHP changes the serialization output in a new version, this function may break.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM