PHP 对象结构可链接性


PHP objecture structure chainability

我正在尝试构建一个依赖于数百个查询的巨大对象结构。为了使其性能高,我采取了以下方法:

  1. 每个查询结果对象都内置到一个对象中。例如,将表"apples"中的结果集构建到苹果对象中。橙色结果将构建为橙色对象。
  2. 每个对象都保存在注册表中,其中注册表是一个全局数组,具有 isExistent($type, $id(、add($type, $obj( 和 get($type, $id( 等函数。我想从第 1 点存储一次每个对象,以便以后访问它,而无需为该对象调用另一个查询(在不同位置多次需要大量对象(。
  3. 我希望对象链接在一起,这样我就可以做类似$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链接到它。这显然会失败,因为我只添加到注册表中,在他们完成构建之后,这显然会失败,因为在此之前他们已经查看了注册表。

我能想到的有两种解决方案:

  1. 扔掉我的可链性,简单地将链接的 ID 存储在我的对象中。因此,我不会在每个字段中存储对父掩码对象的引用,而是简单地存储 id,然后从注册表中检索实际对象。这将是最简单的修复,但会丢弃链条。

  2. 拆分基元对象实例化和复杂属性。只需通过构造函数添加原语,并通过setter将复合体(如实际$mask对象(添加到构造函数之后和注册表::add((之后的每个字段。

在这里最好做什么?我的一般方法有问题吗?

我的目标只是构建一个易于使用的对象结构(将是数百个对象(并减少冗余查询((。这真的需要快速。我也只想要每个不同的对象一次,然后在复杂的对象结构中相应地链接。

谢谢,很抱歉有很长的描述。

好吧,几年前我使用PHP Magic Method __get((为一个项目做了类似的事情。我实际上所做的是将 Getter 对象存储在一个名为 Registry.get 的变量中;像这样:$this->get = new GetterObject($this);.现在,请注意,我将Registry作为变量传递给我的GetterObject,您可能会问"为什么?

工作原理

  1. GetterObject初始化时Registry作为变量(除非Registery作为全局绝对对象,否则不需要这样做!
  2. 您可以使用类似 Registery::get->fruits; 的东西"获取"一个 ORM 对象。
  3. GetterObject将检查对象的Registry数组以查找fruits ORM对象。
  4. GetterObject将返回自身的一个新实例,其中包含一些额外的变量来定义您所处的步骤;类似于 $this->path = "/fruits/";
  5. 现在,当您"获取"第二个对象时,例如Registery::get->fruits->apples;GetterObject将简单地检查哪个是最后的$this->path块,它将依赖于它来查找子元素。请注意,此步骤在很大程度上取决于您如何构建自己的ORM对象数组。
  6. GetterObject将重复步骤4和5,直到你最终得到欲望的对象并做一些类似->return_values();的事情,这是一个定义的函数,返回你正在寻找的实际ORM对象,而不是你用来浏览ORM对象GetterObject

再次提醒一下,这可能不是所有基于 Registry 的平台的最佳实践,因此,在这样做之前,请确保您确实需要如此复杂的东西。否则,一个简单的__get()定义可能就是您所需要的。祝你好运。