所以我决定在PHP中创建一些类,这样我就可以使用< ul>,< li>动态构建一个菜单栏。和< a>标签。原因是因为我想在项目中重复使用它。
首先是代码的Blob,注意我在我的代码中添加了一些调试信息,因为我实际上是一个.NET开发人员而且我不知道如何正常调试:s
<?php
// Menu Items <li><a href=\"$target\">$itemName</a></li>
class MenuItem {
public $order;
public $target;
public $itemName;
function __construct($itemName="", $target="", $order=0) {
$this->order = $order;
$this->target = $target;
$this->itemName = $itemName;
}
public function Build() {
//if $target is empty or $itemName is empty then return empty string (both must be present to generate an item)
if(strcasecmp($target,"") == 0 || strcasecmp($itemName,"") == 0) {
return "";
}
return "<li><a href=\"" . $target . "\">" . $itemName . "</a></li>";
}
}
//<li><a>$FirstMenuItem</i>
// Submenu Root Head Item: <li><a href=\"$(optional)Target\">$ItemName</a><ul>
// Holds a list of MenuItems and SubmenuRootItems
// Submenu Root End Item: </ul>
class SubMenu extends MenuItem {
protected $itemArray;
function __construct($itemName = "", $target = "", $order = 0) {
parent::__construct($itemName, $target, $order);
$this->itemArray = array();
}
public function Items() {
return $this->itemArray;
}
public function AddSubMenuItem ($subMenuItem) {
$retval = strcasecmp( get_class ($subMenuItem), "submenu") == 0 ? self::AddItem($subMenuItem) : false;
echo"<br>second dump<br>";
var_dump($this->itemArray); echo "<br>";
return $retval;
}
public function AddMenuItem ($menuItem) {
$retval = strcasecmp( get_class ($menuItem), "menuitem") == 0 ? self::AddItem($menuItem) : false;
echo"<br>second dump<br>"; //debug code
var_dump($this->itemArray); echo "<br>"; //debug code
return $retval;
}
protected function AddItem($item) {
$itemArray[$item->itemName] = $item;
echo "AddItem <br />"; //ugly debug code
var_dump($itemArray); //even more of it
return true;
}
public function Build() {
$buildHtml = "<li>";
$buildHtml .= strcasecmp($target, "") == 0 ? "<a>" : "<a href=\"" . $target . "\">";
$buildHtml .= $itemName . "</a><ul>";
$buildHtml .= BuildSubMenu(Items());
$buildHtml .= "</ul></li>";
}
public function BuildSubMenu($menuItems) {
$buildHtml = "";
echo "for each start". var_dump($menuItems) ;
foreach($menuItems as $menuItem) {
echo $menuItem;
$buildHtml .= $menuItem->Build();
}
return $buildHtml;
}
}
// Menu Root Element <ul id=\"menu\">
// holds a list of MenuItems and SubmenuRootItems
// Menu Root Closing Element </ul>
class MenuBuilder extends SubMenu {
function __construct() {
parent::__construct();
}
public function Build() { echo "<br><br><br>". var_dump($this->itemArray); echo "<br><br><br>".var_dump(parent::$this->itemArray);echo "<br><br><br>";//ugly debug code
$buildHtml = "<ul id=\"menu\">";
$buildHtml .= parent::BuildSubMenu($this->itemArray);
$buildHtml .= "</ul>";
return $buildHtml;
}
}
?>
问题是整个事情都不起作用,php显然不是.NET,但我真的不知道以下是怎样的。为了测试,我创建了这个小的php页面,它可以调用我的新类。
Write("Create menuBuilder...");
$menuBuilder = new MenuBuilder();
WriteLine("Done!");
Write("Create subMenu1...");
$subMenu1 = new SubMenu("Sub Menu 1");
WriteLine("Done!");
Write("Execute subMenu1->AddMenuItem...");
$subMenu1->AddMenuItem(new MenuItem("Menu Item 1.1", "#1.1"));
WriteLine("Done!");
Write("Create menuItem2...");
$menuItem2 = new MenuItem("Menu Item 2","#2");
WriteLine("Done!");
Write("Execute menuBuilder->AddSubMenuItem...");
$menuBuilder->AddSubMenuItem($subMenu1);
WriteLine("Done!");
Write("Execute menuBuilder->AddMenuItem...");
$menuBuilder->AddMenuItem($menuItem2);
WriteLine("Done!");
之后在$ subMenu和$ menuBuilder上都有一个Items属性的转储
我的浏览器中这些调用的输出完全让我感到困惑:
Create menuBuilder...Done!
Create subMenu1...Done!
Execute subMenu1->AddMenuItem...AddItem
array(1) { ["Menu Item 1.1"]=> object(MenuItem)#4 (3) { ["order"]=> int(0) ["target"]=> string(4) "#1.1" ["itemName"]=> string(13) "Menu Item 1.1" } }
second dump
array(0) { }
Done!
Create menuItem2...Done!
Execute menuBuilder->AddSubMenuItem...AddItem
array(1) { ["Sub Menu 1"]=> object(SubMenu)#3 (4) { ["itemArray":protected]=> array(0) { } ["order"]=> int(0) ["target"]=> string(0) "" ["itemName"]=> string(10) "Sub Menu 1" } }
second dump
array(0) { }
Done!
Execute menuBuilder->AddMenuItem...AddItem
array(1) { ["Menu Item 2"]=> object(MenuItem)#4 (3) { ["order"]=> int(0) ["target"]=> string(2) "#2" ["itemName"]=> string(11) "Menu Item 2" } }
second dump
array(0) { }
Done!
因此AddItem函数工作,一个项目被添加到$ itemArray并成功转储。然后当函数返回它的调用者'AddMenuItem'并且我再次转储相同的$ itemArray时它是空的?我真的不知道这是如何工作的:s
答案 0 :(得分:4)
也许你不会在AddItem方法中更改class itemArray属性?
你有这个:
protected function AddItem($item) {
$itemArray[$item->itemName] = $item;
echo "AddItem <br />"; //ugly debug code
var_dump($itemArray); //even more of it
return true;
}
试试这个:
protected function AddItem($item) {
// $this will change the class property :)
$this->itemArray[$item->itemName] = $item;
echo "AddItem <br />"; //ugly debug code
var_dump($this->itemArray); //even more of it
return true;
}
你不会在很多地方使用$ this,比如MenuItem-&gt; Build方法:
class MenuItem {
public $order;
public $target;
public $itemName;
function __construct($itemName="", $target="", $order=0) {
$this->order = $order;
$this->target = $target;
$this->itemName = $itemName;
}
public function Build() {
// The $target and $itemName variables aren't inicialized
//if $this->target is empty or $this->itemName is empty then return empty string (both must be present to generate an item)
if(strcasecmp($this->target,"") == 0 || strcasecmp($this->itemName,"") == 0) {
return "";
}
return "<li><a href=\"" . $this->target . "\">" . $this->itemName . "</a></li>";
}
}