sergio
sergio

Reputation: 5260

Unexpected result when comparing PHP objects

When I compared two different objects, it returns firstly true, and than after print_r (on objects) returned false.

From PHP manual:

Two object instances are equal if they have the same attributes and values, and are instances of the same class.

But here, in example, I set different values. Why the result is different between PHP 5.4.0 - 5.5.7?

abstract class first
{
    protected $someArray = array();
}     

class second extends first
{    
    protected $someArray = array();        
    protected $someValue = null;

    public function __construct($someValue)
    {
        $this->someValue = $someValue;
    }
}

    $objFirst = new second('123');       
    $objSecond = new second('321');       

    var_dump ($objFirst == $objSecond);    
    print_r($objFirst);    
    var_dump ($objFirst == $objSecond);

Result is:

 bool(true)
 second Object ( [someArray:protected] =>
 Array ( ) [someValue:protected] => 123 )
 bool(false)

But what I expected was:

  bool(false)
  second Object ( [someArray:protected] =>
  Array ( ) [someValue:protected] => 123 )
  bool(false)

Upvotes: 26

Views: 1123

Answers (2)

NikiC
NikiC

Reputation: 101936

This was a bug in PHP. It's fixed now, see the commit. In short:

  • If you extend a class and redefine the same property the properties_table of the object ends up having a NULL value.
  • The comparison code incorrectly aborted comparison when two objects had a NULL value in the properties_table at the same index - reporting the objects as equal. That doesn't make sense of course, because it discards all differences in the following properties. This is fixed now.
  • The reason why print_r changes the result, is that by fetching the properties of the object (get_properties) the properties hashtable is rebuilt (rebuild_properties_table) which uses entirely different (and correct) comparison code.
  • For context, properties_table and properties are two different ways PHP uses to represent properties - the former being way more efficient and used for declared properties and the latter used for dynamic properties. The print_r call effectively makes the object properties dynamic.

Upvotes: 26

jasir
jasir

Reputation: 1471

Well, ok, Identified as bug in php https://bugs.php.net/bug.php?id=66286.

Also here: Unexpected result when comparing PHP objects

Upvotes: 4

Related Questions