4

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.

LF00
  • 27,015
  • 29
  • 156
  • 295
Alex
  • 2,915
  • 5
  • 28
  • 38
  • 2
    Actually the == and === have different function, the == only checks if they are equal and === check if they are identical. This might help. https://stackoverflow.com/questions/80646/how-do-the-php-equality-double-equals-and-identity-triple-equals-comp – Francis G Sep 09 '19 at 02:10
  • 2
    I think this question is relevant, https://stackoverflow.com/questions/5153528/how-check-memory-location-of-variable-in-php. Not sure if this has changed with 7 though, presumption is no though. – user3783243 Sep 09 '19 at 02:10

4 Answers4

5

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.

Leandro Maro
  • 325
  • 1
  • 12
  • The comparison operators are looking only at the value and data type. https://3v4l.org/mtVkU so `if they refer to the same instance of the same class` is incorrect. – user3783243 Sep 09 '19 at 02:11
  • 1
    I think you misunderstood my question. I want to see whether 2 variables are referring to the same object/memory address. They have identical value does not mean they are the same object. For example, when you change A, B also need to be changed because A and B are referring to the same thing. – Alex Sep 09 '19 at 02:16
  • @user3783243 You're contradicting the official PHP documentation? Your example only shows that PHP always does something that is similar to `String.intern()` in Java - Strings with the same value point to the same object. – Erwin Bolwidt Sep 09 '19 at 02:36
  • @ErwinBolwidt Which documentation are you referring to? I'm referring to https://www.php.net/manual/en/language.operators.comparison.php which is what this answer is reffering to. How can you say `Strings with the same value point to the same object`? I can have two different objects with the same value. – user3783243 Sep 09 '19 at 03:04
  • https://www.php.net/manual/en/language.oop5.object-comparison.php "When using the identity operator (===), object variables are identical if and only if they refer to the same instance of the same class." - and the OP is talking about objects if I understand correctly. – Erwin Bolwidt Sep 09 '19 at 04:08
4

=== 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.

LF00
  • 27,015
  • 29
  • 156
  • 295
  • 2
    This is **incorrect**, Check [PHP Comparing Objects](https://www.php.net/manual/en/language.oop5.object-comparison.php): When using the identity operator (===), **object variables are identical if and only if they refer to the same instance of the same class.** – Hazem Feb 25 '21 at 16:37
  • The same instance of the same class not equal to same address. – LF00 Feb 26 '21 at 00:41
  • @LF00 how so? how can "the same instance of the same class" be present twice in memory? – Tobia Sep 01 '22 at 16:02
  • @Tobia: Try with two strings but three names: `$a = 'a'; $b = 'a', $c = &$a;` here `$b === $c` evaluates `true`, but those are not the same address, just the same value. – hakre Oct 14 '22 at 15:27
  • @hakre But those are strings — not objects. The correct answer is to use https://www.php.net/manual/en/function.spl-object-id.php – Jack Dec 10 '22 at 15:37
  • @Jack: For objects `===` compares the identity already, while you could use `spl_object_id()` (or the hash variant), from top of my head its not necessary. In PHP IIRC this one works for variables: https://stackoverflow.com/a/10801721/367456 . – hakre Dec 10 '22 at 15:58
  • @hakre I just finished writing my own answer explaining that before seeing your comment! Yes, `spl_object_id()` is the way to go. – Jack Dec 10 '22 at 16:44
2

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'
Jack
  • 9,615
  • 18
  • 72
  • 112
-1

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.
Martin
  • 5,945
  • 7
  • 50
  • 77