2017-08-16 55 views
4

,我創建了應該比較的組對象。由於它們具有存儲在變量中的PDO連接,所以==運算符將始終返回false,因爲一個變量不相等。有沒有比較這些對象的方法,只是比較這個唯一的PDO變量? 我能想象的唯一方法是檢查每個變量的巨大循環。 如果有人知道更聰明的方式,我會非常高興。比較兩個對象,除了我的PHP項目的pdo var

+1

您可以使用Reflection來比較除了您知道的不同之外的每個值(即,PDO連接) – ishegg

+0

您正在嘗試做什麼**確實**?你試圖比較兩個相同的對象,**期望**對於一個**屬性**是不同的?是的,'=='操作符會將兩個對象視爲false,因爲它們不是相同的對象。你試圖基本上遍歷每個對象的屬性,並檢查**有多少**匹配? –

+0

@ObsidianAge對象完全一樣。我可以使group()== group(),它可以返回false,因爲類在__construct()函數中設置PDO連接到數據庫。我正在尋找一種方法來比較這兩個並忽略PDO連接 – MarvinX

回答

2

使用此功能。它會使用反射來的每個屬性比較,除了$exceptParameter

<?php 
class Test 
{ 
    public $var1; 
    public $pdo; 

    public function __construct($var1, $pdo) 
    { 
     $this->var1 = $var1; 
     $this->pdo = $pdo; 
    } 
} 
$a = new Test("test1", "test2"); 
$b = new Test("test1", "test3"); 
$c = new Test("test2", "test4"); 
function areSameExcept($obj1, $obj2, $exceptParameter) { 
    $ref1 = new ReflectionClass($obj1); 
    $ref2 = new ReflectionClass($obj2); 

    $propertiesObj1 = $ref1->getProperties(); 

    foreach ($propertiesObj1 as $propertyObj1) { 
     if ($propertyObj1->getName() === $exceptParameter) continue; 
     $propertyObj1->setAccessible(true); 
     $valueObj1 = $propertyObj1->getValue($obj1); 

     $propertyObj2 = $ref2->getProperty($propertyObj1->getName()); 
     $propertyObj2->setAccessible(true); 
     $valueObj2 = $propertyObj2->getValue($obj2); 
     if ($valueObj1 !== $valueObj2) { 
      return false; 
     } 
    } 
    return true; 
} 
var_dump(areSameExcept($a, $b, "pdo")); // true 
var_dump(areSameExcept($a, $c, "pdo")); // false 
+0

非常感謝你 – MarvinX

+0

很高興我可以幫助! – ishegg

1

注意:此方法僅適用於不帶私人屬性的類。

您可以創建一個類函數,它接受來自同一個類的另一個對象,並檢查除PDO連接之外的所有其他屬性是否相等。

有兩種方法可以做到這一點,這兩種方法都要求您將其中一個對象作爲參數傳遞給另一個對象進行比較。您可以創建一個函數,明確檢查要在兩個對象之間進行比較的每個屬性,或者可以遍歷參數並跳過您不想檢查的任何參數。

class GroupObj { 
    public $prop1; 
    public $prop2; 
    public $prop3; 
    public $db; 

    public function __construct($prop1 = "", $prop2 = "", $prop3 = "") { 
     $this->db = "connection established here"; 
     $this->prop1 = $prop1; 
     $this->prop2 = $prop2; 
     $this->prop3 = $prop3; 
    } 

    public function equalsTedious($object) { 
     return ($this->prop1 == $object->prop1 && 
       $this->prop2 == $object->prop2 && 
       $this->prop3 == $object->prop3); 
    } 

    public function equals($object) { 
     $result = true; 
     foreach ($this as $key => $value) { 
      # skip properties you don't want to compare 
      if ($key == "db") { 
       continue; 
      } 

      if ($this->{$key} != $object->{$key}) { 
       $result = false; 
       break; 
      } 
     } 

     return $result; 
    } 
} 

$group1 = new GroupObj(1, 2, 3); 
$group2 = new GroupObj(1, 2, 3); 
$group3 = new GroupObj(4, 5, 6); 

if ($group1->equalsTedious($group2)) { 
    echo "Equal but annoying to maintain 1.<br>"; 
} 

if ($group1->equalsTedious($group3)) { 
    echo "Equal but annoying to maintain 2.<br>"; 
} 

if ($group1->equals($group2)) { 
    echo "Equal with the loop version too 1.<br>"; 
} 

if ($group1->equals($group3)) { 
    echo "Equal with the loop version too 2.<br>"; 
} 
+2

如果屬性是私人的,這將不起作用 – ishegg

+1

啊,好點!我會編輯我的答案以反映這一點。如果有人想要一個具有所有公共屬性的類的簡單解決方案,我仍然希望保留它。 – Cubis