跟踪PHP对象属性更改

时间:2009-08-14 00:27:02

标签: php object-persistence

我正在尝试跟踪对PHP变量所做的所有更改。变量可以是对象或数组。

例如它看起来像:

$object = array('a', 'b');

然后使用对象缓存将此对象持久保存到存储中。当php脚本再次运行时。

因此,当脚本第二次运行,或者另一个脚本运行并修改该对象时,我希望跟踪这些修改,无论是在完成它们还是在脚本执行后一次性修改。

例如:

$object[] = 'c';

我想知道'c'被添加到对象中。

现在实际的代码看起来像这样:

$storage = new Storage();
$storage->object = array('a', 'b');

第二次加载:

$storage = new Storage();

var_dump($storage->object); // array('a', 'b')

$storage->object[] = 'c';

我想知道的是'c'被推入$ storage->对象所以在“Storage”类中我可以将该值设置为持久存储。

我尝试了一些方法,但是有缺点。

1)将“Storable”类中的所有对象换行,以跟踪对象的更改

“Storable”类只是将实际数据对象保存为属性,然后提供__get()和__set()方法来访问它。当修改或添加对象的成员/属性时,“可存储”类会注意到这一点。 当访问一个属性时,Storable类上的__get()返回该属性,包含在另一个Storable类中,以便对每个新级别进行递归跟踪。

问题是对象不再是本机数据类型,因此您无法在阵列上运行数组函数。

例如:

$storage = new Storage();

var_dump($storage->object); // array('a', 'b')

array_push($storage->object, 'c'); // fails

因此我们必须将这些数组函数实现为Storable方法。

例如:

$storage = new Storage();

var_dump($storage->object); // array('a', 'b')

$storage->object->push('c');

这一切都很好,但我想知道它是否可能以某种方式使用本机函数,以减少我正在开发的库的开销,同时跟踪更改,以便可以将任何更改添加到持久存储。

2)忘记跟踪更改,只更新整个对象结构

这是保持程序中的对象与实际存储在对象缓存中的对象(可以在不同的机器上)同步的最简单方法。

但是,这意味着整个结构(如具有1000个索引的数组)必须在单个索引更改时通过套接字发送到对象缓存。

3)在本地保留对象的镜像

我还尝试克隆对象,并保持克隆对象不变。然后,当所有处理都由PHP脚本完成时,以递归方式将克隆与修改后的对象进行比较,并将更改的属性提交回对象缓存。

然而,这需要下载整个对象才能使用它。 它还要求对象占用内存的两倍,因为它是克隆的。


我知道这很模糊,但涉及到相当多的代码。如果有人想看到我可以发布的代码,或者把它放在一个开放的SVN仓库上。该项目是开源的,但我还没有建立公共存储库。

2 个答案:

答案 0 :(得分:1)

说实话,我会重新考虑你在做什么。你真的想把PHP变成不是的东西。这是你在Java和C#而不是PHP中看到的那种ORM,它本质上是瞬态的(意味着除了memcache / APC / etc之外,每个请求都会重新创建)。这是复杂的对象缓存和更改跟踪的诅咒。

话虽如此,唯一可以做到这一点的方法是将所有内容包装在超载__get()__set()__isset()以及实现ArrayAccess的内容中。

答案 1 :(得分:1)

由于您的“对象”实际上是一个数组,因此您无法为其添加功能。您使用类方法封装它的想法是正确的方法。在此阶段担心性能优于正确的设计是无关紧要和误导的 - 您使用此方法所产生的开销可能对您的整体应用程序性能无关紧要。

您应该查看SPL数组类,例如ArrayObject。它们提供了完整的阵列式界面,并且易于扩展。