【问题标题】:Comparing two objects except the pdo var比较除 pdo var 之外的两个对象
【发布时间】:2018-01-25 05:09:57
【问题描述】:

对于我的 php 项目,我创建了应该比较的组对象。因为它们有一个存储在变量中的 PDO 连接,所以 == 运算符将始终返回 false,因为一个变量不相等。除了比较这个唯一的 PDO 变量之外,有没有办法比较这些对象? 我能想象的唯一方法是检查每个变量的巨大 for 循环。 如果有人知道更聪明的方法,我会很高兴。

【问题讨论】:

  • 您可以使用反射来比较每个值,除了您知道不同的值(即 PDO 连接)
  • 究竟想做什么?您正在尝试比较两个相等的对象,期望有一个不同的一个属性?是的,== 运算符会将这两个对象等同为 false,因为它们不是相同的对象。您是否试图从本质上遍历每个对象的属性并检查 多少 匹配?
  • @ObsidianAge 对象完全一样。我可以使 group() == group() 并且它可能返回 false,因为该类在 __construct() 函数中设置了与数据库的 PDO 连接。我正在寻找一种方法来比较这两者并忽略 PDO 连接

标签: php object pdo


【解决方案1】:

使用此功能。它将使用反射来比较除$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

【讨论】:

  • 很高兴能帮上忙!
【解决方案2】:

注意:此解决方案仅适用于没有私有属性的类。

您可以创建一个类函数,从同一类中获取另一个对象,并检查除 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>";
}

【讨论】:

  • 啊,好点子!我将编辑我的答案以反映这一点。我仍然想保留它,以防有人想要一个具有所有公共属性的类的简单解决方案。
猜你喜欢
  • 2017-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-02
  • 2014-01-26
  • 2012-08-17
  • 2014-03-02
相关资源
最近更新 更多