Dependence of the processing order in the cycle

I am creating a templating system where I instantiate each tag using a foreach loop. The problem is that some of these tags rely on each other, so I'm wondering how to get around this ordering from the loop.

Here's an example:

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!

      

EDIT: OK to clarify .. My main problem is that class A relies on class B, but class A is instantiated by class B, so the width is not yet defined in class B. I'm looking for a good way to make sure all classes loaded for everyone to create interdependencies. In the future, please don't consider any syntax errors. I just compiled this example locally. Also suppose I have access to class B from class A after instantiating class B.

I know this has applications elsewhere and I'm sure this has been solved before, if someone can enlighten me or point me in the right direction that would be great!

Thanks! Matt Muel

+2


a source to share


3 answers


The easiest way is probably to do a second pass through the array of tag objects as soon as they have been created and call some standard method (see the method template template like http://java.dzone.com/articles/ design-patterns-template-method ) for each example

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

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

      



How the resolveDependencies implementation is implemented will differ from class to class.

+1


a source


Where does this $ B instance come from in A :: construct ()? This is not true.

Possible races:
1) Static values:

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

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

      

2) Static functions:



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

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

      

3) Just in time for the factorymethod (or an object if you need one) if you need objects

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);
}

      

And if you wanted changes in B to be reflected in A, you could always use references instead of assignments. All this of course expects the class definition to be available, define __autoload () if not, or include them all beforehand.

+1


a source


You are missing a width()

method in the class B

that you are calling in the A

class $this->width = $B->width();

(and you must enable or inherit using inheritance to use class B in class A)

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

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

      

As for ordering, you need to be more specific.

0


a source







All Articles