PHP对象结构可链接性

时间:2015-09-24 14:02:24

标签: php

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

  1. 每个查询结果对象都构建到一个对象中。例如,表格中的结果集" apples"被构建成一个苹果对象。橙色结果将构建为橙色对象。
  2. 每个对象都保存在注册表中,其中注册表是一个全局数组,其函数包括isExistent($ type,$ id),add($ type,$ obj)和get($ type,$ id)。我想在此处将点1的每个对象存储一次以便以后访问它而不需要为对象调用另一个查询(在不同的地方需要多次对象)。
  3. 我希望将对象链接在一起,以便我可以执行类似$ tree-> getFruits() - > getApple() - > getPlace() - > getName()的操作。我还希望我的层次结构中的对象在两个方向上链接以供以后使用。
  4. 为什么我需要这个?例如" apple"具有id 3的对象将在实例化$ tree对象时使用一次,在创建$ vitamin对象时使用一次等等。我不想每次向数据库发送另一个查询()时需要此对象。所以我检查一下:

    Registry::isExistent("APPLE", $id)
    

    然后从注册表中获取它,如果它在那里,否则从db调用它,然后另外将它添加到注册表。

    问题:由于显而易见的原因,我得到了无限循环,我可以轻松解决,但我不知道这里最好的方法是什么。

    实际代码(不是上面的苹果和橙子等示例):

    $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. 拆分原始对象实例和复杂属性。只需通过构造函数添加基元,并将实际的$ mask对象之类的复合体添加到构造函数之后的每个字段中,并通过setter在Registry :: add()之后添加。

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

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

      非常感谢和抱歉。

1 个答案:

答案 0 :(得分:0)

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

如何运作

  1. 使用GetterObject作为变量初始化Registry(除非Registery作为全局绝对对象,否则不需要!)。
  2. 你"得到"使用Registery::get->fruits;
  3. 之类的ORM对象
  4. GetterObject将检查Registry对象数组以查找fruits ORM对象。
  5. GetterObject将返回一个新的自身实例,其中包含一些额外的变量,用于定义您所处的步骤;像$this->path = "/fruits/";
  6. 之类的东西
  7. 现在,当你"得到"第二个对象,比如Registery::get->fruits->apples;GetterObject将简单检查哪个是最后一个$this->path片段,它将依赖于它来查找子元素。请注意,此步骤在很大程度上取决于您如何构建自己的ORM对象数组。
  8. GetterObject将重复步骤4和5,直到您最终得到欲望的对象并执行->return_values();之类的操作,这是一个定义的函数,它返回您要查找的实际ORM对象,而不是您用来浏览ORM对象的GetterObject
  9. 再次作为一个小注释,这可能不是所有基于Registry的平台的最佳实践,因此,在这样做之前,请确保您确实需要这么复杂的东西。否则,简单的__get()定义可能就是您所需要的。最好的运气。