【发布时间】:2015-02-24 08:36:56
【问题描述】:
是否有一种更原生的方式(例如内置函数),使用更少的用户空间代码来检查对象属性值是否已更改,而不是使用其中一种方法:
序列化方法
$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);
结果:
f7827bf44040a444ac855cd67adfb502 (initial)
506d1a0d96af3b9920a31ecfaca7fd26 (changed)
Changed: bool(true)
卷影复制方法
$obj = new stdClass();
$shadowObj = clone $obj;
$obj->change = true;
var_dump($shadowObj != $obj);
结果:
bool(true);
这两种方法都有效。但与非用户态实现相比,两者都有缺点。第一个需要 CPU 进行序列化和散列,第二个需要内存来存储克隆。并且某些类可能无法克隆。
PHP 不跟踪对象属性的变化吗? PHP 没有公开一个方法来使用它吗?
【问题讨论】:
-
对于用户空间对象(与 stdClass 对象相反)我会使用观察者
-
您如何定义“已更改”您的意思是属性值的读取方式不同,还是某些代码明确设置了属性?还是别的什么?
-
@deceze 你能解释一下“脏检查”是什么意思吗?那么对你来说什么是“干净的检查”呢?
-
你可以强制使用setter方法而不是直接赋值。这些方法可以跟踪变化。
-
你是对的,但是我不能使用 e.x.
\stdClass。而且我必须将逻辑放入“愚蠢的”getter/setter 方法中。然后我更喜欢一个卷影副本,我可以通过反射检查当前对象的任何更改。
标签: php