Home >Backend Development >PHP Tutorial >Design Patterns - An example of php composition pattern related questions
<code><?php abstract class MenuComponent { abstract function add(MenuComponent $component); abstract function remove(MenuComponent $component); abstract function getName(); abstract function displayOperation(); } class MenuComposite extends MenuComponent { private $_items = array(); private $_name = null; function __construct($name) { $this->_name = $name; } function remove(MenuComponent $component){ } function add(MenuComponent $component) { $this->_items[$component->getName()] = $component; } function getName(){ return $this->_name; } public function displayOperation() { static $align = '|'; $align .=''; echo $this->_name, " <br/>"; foreach($this->_items as $name=> $item) { echo $align; $item->displayOperation(); } } } class Client { static function displayMenu() { $subMenu1 = new MenuComposite('submenu1'); $subMenu1->add($subMenu1); $subMenu1->displayOperation(); } } Client::displayMenu();</code>
The output is an infinite loop
submenu1
|submenu1
|submenu1
...
Why is this happening? After the first recursive call to displayOperation(), the foreach should be empty and then stop. Why is there an infinite loop?
<code><?php abstract class MenuComponent { abstract function add(MenuComponent $component); abstract function remove(MenuComponent $component); abstract function getName(); abstract function displayOperation(); } class MenuComposite extends MenuComponent { private $_items = array(); private $_name = null; function __construct($name) { $this->_name = $name; } function remove(MenuComponent $component){ } function add(MenuComponent $component) { $this->_items[$component->getName()] = $component; } function getName(){ return $this->_name; } public function displayOperation() { static $align = '|'; $align .=''; echo $this->_name, " <br/>"; foreach($this->_items as $name=> $item) { echo $align; $item->displayOperation(); } } } class Client { static function displayMenu() { $subMenu1 = new MenuComposite('submenu1'); $subMenu1->add($subMenu1); $subMenu1->displayOperation(); } } Client::displayMenu();</code>
The output is an infinite loop
submenu1
|submenu1
|submenu1
...
Why is this happening? After the first recursive call to displayOperation(), the foreach should be empty and then stop. Why is there an infinite loop?
Implementation of
add $this->_items[$component->getName()] = $component;
Note$subMenu1->add($subMenu1);
The attribute $_items["submenu1"] of instance $subMenu1 is itself
$subMenu1
Then it goes on endlessly...
The class attribute $this->item is always the object you instantiate and pass in, so the displayOperation() method keeps looping