PHP比较对象 - 奇怪的行为

时间:2013-12-13 12:38:49

标签: php oop object compare

测试我自己的模块进行验证时,我发现了某种问题。 我真的不知道发生了什么,我无法解释。

也许我太累了,或者PHP只是吓坏了。 可以有人告诉我出了什么问题吗?

我想比较对象(因为我想检查该对象是否已存在于数组中)

在PHP手册中,我们可以阅读:

  

比较对象

     

在PHP 5中,对象比较比PHP 4更复杂   根据人们对面向对象语言的期望   (不是PHP 5就是这样的语言)。

     

使用比较运算符(==)时,会比较对象变量   以一种简单的方式,即:两个对象实例是相等的   具有相同的属性和值,并且是相同的实例   类。

所以,让创建简单代码将使用它

class A
{
    protected $property;

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

$object1 = new A('ABC');
$object2 = new A('XYZ');

// Instances are not equal because of different value of property
var_dump($object1 == $object2); // Will return bool(false)

好的,PHP告诉我们对象不等 - 这是正确的。

所以现在我决定使用我班级的对象。 我为构造函数提供了不同的参数(这些参数将被设置为类属性)

echo "Start";

// Creating an instance of class with some parameters
// Each of parameter will be stored as class property
$object1 = new ComparsionRule('ABadasdC', ComparsionRule::LESS_THAN_OR_EQUAL);

// Creating an instance of class with some different parameters
// Each of parameter will be stored as class property
$object2 = new ComparsionRule('XYZ', ComparsionRule::NOT_EQUAL_TO);

// Two instances should not be equal (false expected)
var_dump($object1 == $object2); // Will return bool(true)

// Printing content of first object 
var_dump($object1);

// Printing content of second object
var_dump($object2);

// Checking the expression again
// Two instances should not be equal (false expected)
var_dump($object1 == $object2); // Will return bool(false)

echo "End";
die;

结果令人惊讶,因为首先PHP告诉我们对象相等然后打印这些对象,之后再次比较对象但现在对象不相等

您可以在下方找到结果:

Result

我没有使用任何魔术方法 (除了构造),我无法显示 ComparsionRule 的内容(许可证禁止)

另一个有趣的事实:

当我删除 $ _ errorDefinitions 属性时,它开始正常运行。类似的时候我更改了属性顺序($ _type和$ _compareValue早于$ _errorDefinitions定义)

我不想获得其他解决方案我只想知道它为什么会这样工作?

有人可以解释一下吗?

3 个答案:

答案 0 :(得分:3)

因为PHP正在疯狂!

<?php

class A {
    public $property;
    public function __construct($value) {
        $this->property = $value;
    }
}

$object1 = new A('Hello World');
$object2 = new A(0);

var_dump($object1 == $object2);

不要依赖==来提供PHP对象之间的任何有意义的比较。如果您需要检查两个对象是否是同一个实例,请使用===;否则为类本身添加一个有意义的比较方法。

在没有看到ComparisonRule的代码的情况下,我无法真正猜出出现什么特别错误。我通常会假设某些对象属性正在进行某种延迟初始化,这样在第一次比较时没有初始化属性(因此==认为它们相等),但是通过转储来初始化对象。但是,如果不使用更多魔术方法,我认为这是不可行的。

答案 1 :(得分:0)

我再次使用它,我发现了新的

我创建了显示此行为的简单代码,因此您不再需要查看我的类代码,因为您现在可以自行测试。

所以也许现在有人会解释发生了什么?

<?php

// Printing "START"
echo 'START';

/**
 * Simple abstract class with one
 * protected property
 */
abstract class A
{
    /**
     * An errors array property
     * @var array
     */
    protected $errors = array();
}

/**
 * Simple class which extends A
 */
class B extends A
{
    /**
     * An errors array property
     * @var array
     */
    protected $errors = array();

    /**
     * Value from constructor
     * @var string
     */
    protected $value = null;

    /**
     * Method stores value in property
     * 
     * @access  public
     * @param   string  $value  Value to store
     * @return  void
     */
    public function __construct($value)
    {
        $this->value = $value;
    }
}

// Creating new instance of B with "ABC" string
$object1 = new B('ABC');

// Creating new instance of B with "CBA" string
$object2 = new B('CBA');

// Both objects got different value of $value property
// They should be different, but PHP returns true here
var_dump($object1 == $object2);

// Printing first object
var_dump($object1);

// Printing second object
var_dump($object2);

// Comparing objects again but now PHP returns false
var_dump($object1 == $object2);

// Printing "END"
echo 'END';
die;

答案 2 :(得分:0)

是的,这是一个PHP错误,您可以在下面找到更多详细信息:

https://bugs.php.net/bug.php?id=66286