我有一个班级AdminMenu
,我用它来为我的项目创建管理员菜单。这是班级:
class AdminMenu{
public $menu = array(
'Groups and Statuses' => 'groups',
'Members Management' => 'members',
'Book Manager' => 'books',
'Activity Log' => 'activities',
'Quiz Maker' => 'quiz',
'Other' => 'other'
);
public function AdminMenu() {
$html = "<nav><ul><li><input type='text' id='search' placeholder='Search' /></li>";
foreach($this->menu as $text => $link){
$html .= '<li><a href="'. site_url(array('admin', $link)) .'">'. $text .'</a></li>';
}
$html .= '</ul></nav>';
echo $html;
}
}
正如您所看到的,构造函数是回显数据,这很好。因此,当我需要管理员菜单时,我可以致电new AdminMenu();
,看起来很棒。
问题是,CodeIgniter建议将类保留在libraries
目录中并像这样调用它:$this->load->library('adminMenu');
。问题是,由于某种原因它在这里调用构造函数,所以如果我加载它,然后创建一个新的AdminMenu()
,构造函数总共被调用了2次,所以我有两个菜单。
加载库是否意味着调用构造函数,我错了吗?我应该为输出创建不同的功能吗?或者我可以将其保留在libraries
中,并将其称为包含类吗?
谢谢!
答案 0 :(得分:4)
CodeIgniter的加载将始终在控制器的本地范围内创建类的单个实例。这就是他们设计的方式。 (我个人不喜欢这种方法。)
因此,如果您要将您的类构建为CodeIgniter库,您将只希望构造函数执行构建任务(无论如何在OO中都是可取的),并且有一个单独的方法来检索菜单
(或者,您可以使用自己的外部加载直接加载您的类,例如通过添加SPL自动加载器)。
无论如何,试着这样做:
class AdminMenu
{
public $menu = array(
'Groups and Statuses' => 'groups',
'Members Management' => 'members',
'Book Manager' => 'books',
'Activity Log' => 'activities',
'Quiz Maker' => 'quiz',
'Other' => 'other'
);
public function __construct()
{
}
public function getMenu()
{
$html = "<nav><ul><li><input type='text' id='search' placeholder='Search' /></li>";
foreach($this->menu as $text => $link){
$html .= '<li><a href="'. site_url(array('admin', $link)) .'">'. $text .'</a></li>';
}
$html .= '</ul></nav>';
return $html;
}
}
然后像这样使用它:
$this->load->library('adminMenu');
echo $this->adminMenu->getMenu();
我还建议将makinng $ menu私有而非公开。
答案 1 :(得分:2)
CodeIgniter使用Singleton方法。它们会在加载时自动实例化您的类。
您应该使用现有的实例,例如
$this->adminMenu->foo();
另一方面,不建议从构造函数执行输出。 Constructors旨在构建对象的内部状态而不是执行操作。将输出移动到可以调用的方法。
还有一件事:在PHP中(与Java不同),建议将构造函数命名为__construct
,而不是使用类名。请参阅this。