处理循环中的顺序依赖性

时间:2010-05-15 09:28:33

标签: php class for-loop

我正在制作一个模板系统,我使用foreach循环实例化每个标签。问题是一些标签相互依赖,所以我想知道如何绕过循环中的那个排序。

以下是一个例子:

Class A {
  public $width;
  __construct() {
     $this->width = $B->width; // Undefined! Or atleast not set yet..
  }

}

Class B {
  public $width;
  __construct() {
     $this->width = "500px";
  }
  __tostring() {
      return "Hello World!";
  }
}

的template.php

$tags = array("A", "B");
foreach ($tags as $tag) {
   $TagObj[$tag] = new $tag();
}

echo $TagObj['A']->width; // Nadamundo!

编辑:好的只是为了澄清.. 我的主要问题是A类依赖于B类,但A类在B类之前被实例化,因此宽度尚未定义在B类中。我正在寻找一种好的方法来确保为每个人加载所有类,从而允许存在相互依赖性。对于将来,请不要考虑任何语法错误..我只是当场编写了这个例子。还假设在B类实例化后我可以从A类访问B类。

我知道这在其他地方也有应用,我确信之前已经解决了这个问题,如果有人能够启发我,或者指出我的方向很好,那就太棒了!

谢谢! 马特穆勒

3 个答案:

答案 0 :(得分:1)

最简单的方法可能是通过对标记对象数组进行第二次传递,一旦它们全部被实例化,并在每个标记对象上调用一些标准方法(参见模板方法模式,例如http://java.dzone.com/articles/design-patterns-template-method

$tags = array("A", "B");
foreach ($tags as $tag) {
   $TagObj[$tag] = new $tag();
}

foreach (array_keys($TagObj) as $tagName) {
   $TagObj[$tagName]->resolveDependencies($TagObj);
}

如何实现resolveDependencies会因类而异。

答案 1 :(得分:1)

A :: construct()中的这个$ B实例来自哪里?它不在范围内。

可能的解决方案:
1)静态值:

class B {
    static $width = '500px';
...

class A {
    function construct(){
        $this->width = B::$width;
     }

2)静态功能:

class B {
    static function width(){
         return '500px';
...

class A {
    function construct(){
        $this->width = B::width();
     }

3)及时工厂方法(如果需要,可以是对象),如果需要对象

function getTag($name){
    global $TagObj;
    if(!isset($TagObj[$name]) && class_exists($name)){
         $TagObj[$name] = new $name();
    }
    return $TagObj[$name];
}

class A {
    function construct(){
        $this->width = getTag('B')->width();
     }
....
$tags = array("A", "B");
foreach ($tags as $tag) {
   $TagObj[$tag] = getTag($tag);
}

如果您希望B中的更改反映在A中,您可以始终使用引用而不是分配。所有这些当然要求类定义可用,如果没有,则定义__autoload(),或者事先包含它们。

答案 2 :(得分:0)

您在width()B中调用的A类中缺少$this->width = $B->width();方法(并且您应该包含或使用继承来使用B类)一类)

Class B {
  private $width;
  __construct() {
     $this->width = "500px";
  }
  __tostring() {
      return "Hello World!";
  }

  function width() {
   return $this->width;
  }
}

至于订购,你应该更具体。