在PHP中比较两个对象最快的方法是什么?

0x6upsns  于 2023-01-16  发布在  PHP
关注(0)|答案(4)|浏览(120)

假设我有一个对象--在本例中是User对象--我希望能够用一个单独的类来跟踪对的更改。User对象不应该以任何方式更改它的行为。
因此,我的独立类创建了一个“干净”的副本,将其存储在本地某个地方,然后可以将User对象与原始版本进行比较,以查看在其生命周期中是否有任何更改。
是否有函数、模式或任何东西可以快速比较User对象的两个版本?

选项1也许我可以序列化每个版本,然后直接比较,或者散列它们并比较?
选项2也许我应该简单地创建一个ReflectionClass,运行该类的每个属性,看看两个版本是否具有相同的属性值?
选项3也许有一个简单的本机函数,如objects_are_equal($object1,$object2);

最快的方法是什么?

hts6caw3

hts6caw31#

访问一个对象的所有属性(public、protected和private)而不修改它的唯一方法是通过reflection。如果你愿意,你可以在修改之前对对象进行clone,然后使用反射函数循环两个对象中的一个的不同属性并比较它们的值。这将有效地告诉你哪些属性发生了变化。
如果你只想知道对象是否发生了变化,你可以使用==或===操作符,看看PHP文档的comparing objects部分。
也就是说,在您更改它们时跟踪您所更改的内容不是更容易吗?

i7uaboj4

i7uaboj42#

下面是一段支持私有属性的代码:

$reflection_1 = new \ReflectionClass($object_1);
$reflection_2 = new \ReflectionClass($object_2);

$props_1 = $reflection_1->getProperties();

foreach ($props_1 as $prop_1) {

    $prop_1->setAccessible(true);
    $value_1 = $prop_1->getValue($object_1);

    $prop_2 = $reflection_2->getProperty($prop_1->getName());

    $prop_2->setAccessible(true);
    $value_2 = $prop_2->getValue($object_2);

    if ($value_1 === $value_2) {
        // ...
    } else {
        // ...
    }
}

请注意,如果$object_1具有$object_2没有的属性,则上述代码在尝试访问这些属性时将产生错误。
对于这种情况,首先需要将$reflection_1->getProperties()$reflection_2->getProperties()相交。

vm0i2vca

vm0i2vca3#

www.example.com上有一整页php.net专门处理比较对象:
http://php.net/manual/en/language.oop5.object-comparison.php
也是一个很好的阅读:
http://www.tuxradar.com/practicalphp/6/12/0
我认为您应该在复制对象时使用“clone”方法,然后按照www.example.com文章中所述进行比较php.net。
另外一个快速的方法是在类中声明一个静态方法,它只比较相关的“属性”,比如“用户名”,“密码”,“cookie”,...

class User
    {
    
    public $username;
    public $password;
    public $cookie;
    
    # other code
    
    public static function compare(&$obj1, &$obj2)
    {
    if ($obj1->username != $obj2->username)
        return 0
    if ($obj1->password != $obj2->password)
        return 0
    if ($obj1->cookie != $obj2->cookie)
        return 0
    return 1
    }
    
    
    };
monwx1rj

monwx1rj4#

通过反射比较dto类的简单示例

class InvoiceDetails
{
    /** @var string */
    public $type;

    /** @var string */
    public $contractor;

    /** @var string */
    public $invoiceNumber;

    /** @var \DateTimeInterface|null */
    public $saleDate;

    /** @var \DateTimeInterface|null */
    public $issueDate;

    /** @var \DateTimeInterface|null */
    public $dueDate;

    /** @var string */
    public $payment;

    /** @var string */
    public $status;

    public function isEqual(InvoiceDetails $details): bool
    {
        $reflection = new \ReflectionClass(self::class);

        /** @var \ReflectionProperty $property */
        foreach ($reflection->getProperties() as $property) {
            $name = $property->getName();
            if ($this->$name !== $details->$name) {
                return false;
            }
        }

        return true;
    }

}

相关问题