2013-12-13 536 views
3

雖然測試我自己的模塊進行驗證我發現了一些問題。 我真的不知道發生了什麼,我無法解釋它。PHP比較對象 - 奇怪的行爲

也許我很累或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和超過$ _errorDefinitions前面定義$ _compareValue)

我不希望得到替代的解決方案我只想知道爲什麼它的工作也是這樣嗎?

有人可以解釋我嗎?

回答

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的代碼,我不能真正冒險猜測什麼是具體出錯。我通常會假設某些對象屬性的惰性初始化正在進行,因此屬性在第一次比較中未初始化(因此==將它們視爲相等),但通過轉儲對象進行初始化。但是,如果不使用更多的魔法方法,我認爲這是不可行的。

+0

嗯,是啊,與詮釋你的榜樣(0)和字符串清除我的腦海裏。 我沒有注意到PHP是比較屬性值與「==」運算符,我知道PHP的行爲奇怪,它:) 我會檢查它,我會很快發佈答案。 –

+0

我只是用簡單的代碼添加了新的答案,它顯示了行爲。 –

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; 
+0

我設法[進一步減少](https://gist.github.com/tobyink/7945258)。我看不到任何合理的原因,這幾乎肯定是PHP中的一個錯誤。 – tobyink

+0

好吧,我會在https://bugs.php.net上報告它 –