检查对象是否已更改

TiM*_*TER 10 php

是否有更原生的方式(来自内置函数)用较少的用户空间代码来检查对象属性值是否已更改而不是使用以下方法之一:

序列化方法

$obj = new stdClass(); // May be an instance of any class

echo $hashOld = md5(serialize($obj)) . PHP_EOL;

$obj->change = true;

echo $hashNew = md5(serialize($obj)) . PHP_EOL;

echo 'Changed: '; var_dump($hashOld !== $hashNew);
Run Code Online (Sandbox Code Playgroud)

结果如下:

f7827bf44040a444ac855cd67adfb502 (initial)
506d1a0d96af3b9920a31ecfaca7fd26 (changed)
Changed: bool(true)
Run Code Online (Sandbox Code Playgroud)

影子复制方法

$obj = new stdClass();
$shadowObj = clone $obj;

$obj->change = true;

var_dump($shadowObj != $obj);
Run Code Online (Sandbox Code Playgroud)

结果如下:

bool(true);
Run Code Online (Sandbox Code Playgroud)

两种方法都有效.但是与非用户区实现相比,两者都有缺点.第一个需要CPU进行序列化和散列,第二个需要内存来存储克隆.有些课程可能无法克隆.

PHP是否跟踪对象属性的更改?PHP没有公开一种方法来使用它吗?

Jac*_*ski 4

你想做什么?

在一系列“未知”操作之后,您试图将对象与其自身进行比较,以检查对象是否已更改。如果这是真的,那么就有一些逻辑点需要观察。首先,如果你想将对象与其自身进行比较,你只有两个选择:

  1. 记住整个对象状态(例如哈希,或者只是复制整个对象)
  2. 跟踪随时间的变化

没有其他合乎逻辑的方法。比较内存分配、真实对象、复制对象、比较哈希值,都是第一点。跟踪更改、保存对象内部的更改、记住同时操作,在第 2 点中。

所以在我看来这个问题是一种备份数据问题。在这种情况下,有很多很多解决方案,但就我而言,它们都没有硬编码在 php 中。为什么?


答案很简单。PHP 人员也遇到了与您相同的问题:)。因为如果这在 php 内部被硬编码,那么 php 应该运行/使用这些机制 (1) 或 (2) 之一。

在这种情况下,您创建的每个对象以及您所做的每个操作都应该写在某个地方,以记住每个状态/对象/某些内容,并在将来使用它们进行比较。

虽然您需要此解决方案,但几乎~100%大多数网站都不需要。因此,在 php 中硬编码会使~100%网站运行速度变慢,而你的工作速度更快;)。


PHP 假设的解决方案?

我能想到的唯一解决方案(将来可能在 php 中构建)是制作某种 php 配置标志:track objects,并且仅当该标志为 时true,才运行跟踪对象状态的所有 php 机制。但这也意味着巨大的性能差距。正如所有的ifs(如果跟踪,如果跟踪,如果跟踪)也消耗处理器和内存时间。

还有一个问题,比较什么?您需要将对象与相同对象进行比较,但是......几分钟前?前几次操作?不...您必须精确地指向代码中的一个位置,然后指向代码中的第二个位置并比较这两个位置中的对象。所以假设的自动跟踪......有点无能为力,因为提供时间数组的对象状态中没有“密钥” 。我的意思是,即使你有magic_object_comparer功能,它应该是什么样子?

<?php

    function magic_object_comparer() {} // Arguments??
    function magic_object_comparer($object_before, $object_after) {} // you must save object_before somewhere...??
    function magic_object_comparer($object, $miliseconds) {} // How many miliseconds?
    function magic_object_comparer($object, $operations) {} // How many operations? Which operations?


    magic_comparer_start($object);
    // ... Few operations...
    $boolean = magic_comparer_compare_from start($object);
    // Same as own implementation...
?>
Run Code Online (Sandbox Code Playgroud)

可悲的是,你只剩下自己的实现......

毕竟,我建议为此实现某种自己的机制,并记住只在需要的地方使用它。因为这种机制肯定会消耗时间和内存。所以仔细想想:

  1. 您要比较哪些对象。为什么?
  2. 当你想比较它们时?
  3. 所有的变化都需要比较吗?
  4. 保存这些状态更改的最简单方法是什么?

在完成所有这些之后,尝试实施它。我发现您拥有丰富的 php 知识,所以我很确定您会弄清楚一些事情。在这个问题和讨论中也有很多评论和可能的想法。


但毕竟也许我解释了一点为什么没有内置解决方案,以及为什么将来不应该有一个......:)。


更新

看看这里: http: //www.fluffycat.com/PHP-Design-Patterns/。这是关于 php 模式的很棒的资源。您应该看看适配器装饰器观察者模式,以获得可能的优雅的面向对象解决方案。