2

我正在尝试跟踪对 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->object 所以在“Storage”类中我可以将该值设置为持久存储。

我尝试了一些方法,这些方法有效,但也有缺点。

1)将所有对象包装在一个“可存储”类中,该类跟踪对象的更改

“Storable”类只是将实际数据对象保存为属性,然后提供 __get() 和 __set() 方法来访问它。当对象的成员/属性被修改或添加时,“Storable”类会注意到这一点。当访问 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 存储库上。该项目是开源的,但我还没有建立一个公共存储库。

4

2 回答 2

1

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

话虽这么说,你能做到这一点的唯一方法是将所有东西包装在重载__get()和实现的__set()东西中。__isset()ArrayAccess

于 2009-08-14T00:34:06.917 回答
1

由于您的“对象”实际上是一个数组,因此您无法为其添加功能。您用类方法封装它的想法是正确的方法。在这个阶段担心性能而不是适当的设计是无关紧要的,而且是错误的——你用这种方法产生的开销可能对你的整体应用程序性能来说是微不足道的。

您应该查看 SPL 数组类,例如ArrayObject。它们提供了一个完整的类数组接口,并且易于扩展。

于 2009-08-14T00:35:51.027 回答