我正在尝试构建一个依赖于数百个查询的巨大对象结构。为了使其性能高,我采取了以下方法:
- 每个查询结果对象都内置到一个对象中。例如,将表"apples"中的结果集构建到苹果对象中。橙色结果将构建为橙色对象。
- 每个对象都保存在注册表中,其中注册表是一个全局数组,具有 isExistent($type, $id(、add($type, $obj( 和 get($type, $id( 等函数。我想从第 1 点存储一次每个对象,以便以后访问它,而无需为该对象调用另一个查询(在不同位置多次需要大量对象(。
- 我希望对象链接在一起,这样我就可以做类似$tree->getFruits((->getApple((->getPlace((->getName((之类的事情。我还希望层次结构中的对象双向链接以供以后使用。
我为什么需要这个?例如,id 为 3 的"apple"对象将在实例化$tree对象时使用一次,在创建$vitamins对象时使用一次,等等。我不想每次需要此对象时都向数据库发送另一个 query((。所以我检查类似的东西:
Registry::isExistent("APPLE", $id)
然后从注册表中获取它(如果它在那里(,否则从数据库调用它,然后将其另外添加到注册表中。
问题:由于显而易见的原因,我得到了无限循环,我可以很容易地修复,但我不知道这里最好的方法是什么。
实际代码(不是上面苹果和橙子之类的示例(:
$mask = new Mask($row["maskId"], $row["maskName"]);
foreach (Fields::getFieldsFor($mask->getId()) as $field) {
$mask->addField($field);
}
Registry::add("MASK", $mask);
和面具领域的吸气剂:
$mask = Registry::receive("MASK", $row["maskId"]);
$category = Registry::receive("FIELDTYPE", $row["fieldCategory"]);
$field = new Field($row["fieldId"], $category, $row["fieldQuestion"],
$row["fieldDescription"], $row["fieldPosition"], null, null, null, $mask);
Registry::add("FIELD", $field);
这将产生一个无限循环。掩码由多个字段组成。在构建$mask对象时,我希望在$mask数组中链接每个字段。在构建每个$field对象时,我想将父级$mask链接到它。这显然会失败,因为我只添加到注册表中,在他们完成构建之后,这显然会失败,因为在此之前他们已经查看了注册表。
我能想到的有两种解决方案:
扔掉我的可链性,简单地将链接的 ID 存储在我的对象中。因此,我不会在每个字段中存储对父掩码对象的引用,而是简单地存储 id,然后从注册表中检索实际对象。这将是最简单的修复,但会丢弃链条。
拆分基元对象实例化和复杂属性。只需通过构造函数添加原语,并通过setter将复合体(如实际$mask对象(添加到构造函数之后和注册表::add((之后的每个字段。
在这里最好做什么?我的一般方法有问题吗?
我的目标只是构建一个易于使用的对象结构(将是数百个对象(并减少冗余查询((。这真的需要快速。我也只想要每个不同的对象一次,然后在复杂的对象结构中相应地链接。
谢谢,很抱歉有很长的描述。
好吧,几年前我使用PHP Magic Method __get((为一个项目做了类似的事情。我实际上所做的是将 Getter 对象存储在一个名为 Registry.get
的变量中;像这样:$this->get = new GetterObject($this);
.现在,请注意,我将Registry
作为变量传递给我的GetterObject
,您可能会问"为什么?
工作原理
GetterObject
初始化时Registry
作为变量(除非Registery
作为全局绝对对象,否则不需要这样做!- 您可以使用类似
Registery::get->fruits;
的东西"获取"一个 ORM 对象。 GetterObject
将检查对象的Registry
数组以查找fruits
ORM对象。GetterObject
将返回自身的一个新实例,其中包含一些额外的变量来定义您所处的步骤;类似于$this->path = "/fruits/";
。- 现在,当您"获取"第二个对象时,例如
Registery::get->fruits->apples;
,GetterObject
将简单地检查哪个是最后的$this->path
块,它将依赖于它来查找子元素。请注意,此步骤在很大程度上取决于您如何构建自己的ORM对象数组。 GetterObject
将重复步骤4和5,直到你最终得到欲望的对象并做一些类似->return_values();
的事情,这是一个定义的函数,返回你正在寻找的实际ORM对象,而不是你用来浏览ORM对象GetterObject
。
再次提醒一下,这可能不是所有基于 Registry
的平台的最佳实践,因此,在这样做之前,请确保您确实需要如此复杂的东西。否则,一个简单的__get()
定义可能就是您所需要的。祝你好运。