Reputation: 3249
I am new in PHP and in Design Patterns. I have been studying the book Head First - Design patterns with codes in Java. This is the PHP version of one of its Composite Patterns. However, I am getting strange errors with the array $menuComponents
presented below inside class Menu
.
<?php
abstract class MenuComponent{
// Composite Methods
function add(MenuComponent $menuComponent){
throw new RuntimeException("Erro!");
}
function remove(MenuComponent $menuComponent){
throw new RuntimeException("Erro!");
}
function getChild($i){
throw new RuntimeException("Erro!");
}
// Operation Methods
function getName(){
throw new RuntimeException("Erro!");
}
function getDescription(){
throw new RuntimeException("Erro!");
}
function getPrice(){
throw new RuntimeException("Erro!");
}
function isVegetarian(){
throw new RuntimeException("Erro!");
}
function printMethod(){
throw new RuntimeException("Erro!");
}
}
class MenuItem extends MenuComponent{
private $name;
private $description;
private $vegetarian;
private $price;
public function __construct($name,$description,$vegetarian,$price){
$this->name=$name;
$this->description=$description;
$this->vegetarian=$vegetarian;
$this->price=$price;
}
public function getName(){
return $this->name;
}
public function getDescription(){
return $this->description;
}
public function getPrice(){
return $this->price;
}
public function isVegetarian(){
return $this->isVegetarian;
}
public function printMethod(){
echo ' '.$this->name.' ';
if($this->isVegetarian){
echo 'v ';
}
echo $this->price;
echo '<br>';
}
}
class Menu extends MenuComponent{
private $name;
private $description;
private $menuComponents=array();
public function __construct($name,$description) {
$this->name = $name;
$this->description = $description;
}
public function add(MenuComponent $menuComponent) {
$this->menuComponents=array_push($this->menuComponents,$menuComponent);
}
public function remove(MenuComponent $menuComponent) {
$this->menuComponents=array_diff($this->menuComponents,$menuComponent);
}
public function getChild($i) {
return $this->menuComponents[$i];
}
public function getName() {
return $this->name;
}
public function getDescription() {
return $this->description;
}
public function printMethod(){
echo ' '.$this->getName().", ";
echo ' '.$this->getDescription()."<br>";
echo "---------------------- <br>";
foreach($this->menuComponents as $components){
echo $components->printMethod()."<br>";
}
}
}
class Waitress{
private $allMenus;
public function __construct(MenuComponent $allMenus){
$this->allMenus=$allMenus;
}
public function printMenu(){
$this->allMenus->printMethod();
}
}
$pancakeHouseMenu=new Menu('PANCAKE HOUSE MENU','Breakfast');
$dinnerMenu=new Menu('DINNER MENU','Lunch');
$cafeMenu=new Menu('CAFE MENU','Dinner');
$dessertMenu=new Menu('DESSERT MENU','Desert of course');
$allMenus=new Menu('All Menus','All menus combined');
$allMenus->add($pancakeHouseMenu);
print_r($allMenus);
$allMenus->add($dinnerMenu);
$allMenus->add($cafeMenu);
$dinnerMenu->add(new MenuItem('Past', 'Spagueti with sauce', true, 3.89));
$dinnerMenu->printMethod();
The output of print_r is
Menu Object ( [name:Menu:private] => All Menus [description:Menu:private] => All menus combined [menuComponents:Menu:private] => 1 )
Note that there is a strange "1" inside menuComponents, where it should be $dinnerMenu
After this print_r
I get the following errors:
Warning: array_push() expects parameter 1 to be array, integer given in /var/www/DesignPatternHeadFirst/compositePattern.php on line 80
Warning: array_push() expects parameter 1 to be array, null given in /var/www/DesignPatternHeadFirst/compositePattern.php on line 80
And then the output of $dinnerMenu->printMethod()
is
DINNER MENU, Lunch
----------------------
and then another error
Warning: Invalid argument supplied for foreach() in /var/www/DesignPatternHeadFirst/compositePattern.php on line 102
I must be doing something very wrong! What is it?
I appreciate any help!
Upvotes: 1
Views: 60
Reputation: 152246
You are doing:
public function add(MenuComponent $menuComponent) {
$this->menuComponents=array_push($this->menuComponents,$menuComponent);
}
You have to remember, that array_push
returns integer, so you override this array type field with integer value.
Try with:
public function add(MenuComponent $menuComponent) {
array_push($this->menuComponents,$menuComponent);
}
Upvotes: 3