【发布时间】:2012-04-12 14:53:39
【问题描述】:
我正在制作一个小的 PHP MVC 框架来取乐。我正在使用前端控制器index.php 来路由所有流量并根据要求调用新控制器。但是,我需要一种方法来仅根据控制器的名称(基本上是文件名,即controllers/posts.php)来创建用户生成的控制器的实例。
有没有办法做到这一点?
【问题讨论】:
标签: php model-view-controller oop class
我正在制作一个小的 PHP MVC 框架来取乐。我正在使用前端控制器index.php 来路由所有流量并根据要求调用新控制器。但是,我需要一种方法来仅根据控制器的名称(基本上是文件名,即controllers/posts.php)来创建用户生成的控制器的实例。
有没有办法做到这一点?
【问题讨论】:
标签: php model-view-controller oop class
有几种方法可以做到这一点。一种方法是建立一个约定,使得类的名称基于文件的名称。另一种方法是解析文件以获取类的名称。你想看一些小的代码示例吗?
编辑:简单示例
假设我们在某个核心 MVC 控制器中,我们想要加载由第三方用户提供的控制器。您需要做两件事:
假设您有一个约定,例如 Zend,其中类名映射到文件系统,因此控制器可能是
MyProject/Controller/Login.php
登录控制器的路径,相对于项目的根目录。按照 Zend 约定,类的名称是MyProject_Controller_Login。如果你想实例化这个类,你所要做的就是:
// load class
require_once 'MyProject/Controller/Login.php';
// instantiate class
$oUserController = new MyProject_Controller_Login();
如果需要根据运行时数据实例化类,可以使用保存类名的变量来实现,所以
$sUserController = 'MyProject_Controller_Login';
$oUserController = new $sUserController();
希望这足以让您滚动;如果您需要更多,请告诉我。
【讨论】:
是的,在您的前端控制器或路由器类中检查控制器文件是否存在后,您可以调用它: 以下是我从路由器类中提取的一些方法,它们可能对您有所帮助,它是一个示例,但如果您遵循,您可以看到如何加载类以及如何调用方法或操作:
<?php
/**
* Load Class based on controller or action
*/
public function load_controller(){
/*Get the route*/
$this->getController();
/*Assign front controller to handle routes that dont have core controller
eg ./core/controllers/($this->file.Controller).php
*/
if (is_readable($this->file) === false){
$this->file = $this->path.'/frontController.php';
$this->subaction = $this->action;
$this->action = $this->controller;
$this->controller = 'front';
}
/*Include core controller file*/
include($this->file);
/*Create controllers class instance & inject registry*/
$className = $this->controller.'Controller';
$controller = new $className($this->registry);
/*Check the action method is callable within the class*/
if (is_callable(array($controller, $this->action)) === false){
//index() method because not found method
$action = 'index';
}else{
//action() method is callable
$action = $this->action;
}
/*Run the action method*/
$controller->$action();
}
private function getController() {
$route = (!isset($_GET['route']))?'':$this->registry->function->cleanURL($_GET['route']);
/*Split the parts of the route*/
$parts = explode('/', $route);
$this->request = $route;
$corefolders=array('core','templates');
if (empty($route) || in_array($parts[0],$corefolders)){
$route = 'index';
}else{
//Assign which controller class
$this->controller = $parts[0];
if(isset($parts[1])){
/* Site.com/action */
$this->action = $parts[1];
}
if(isset($parts[2])){
/* Site.com/action/subaction */
$this->subaction = $parts[2];
}
}
/*Set controller*/
if (empty($this->controller)){$this->controller = 'index';}
/*Set action*/
if (empty($this->action)){$this->action = 'index';}
/*Set the file path*/
$this->file = $this->path.'/'.$this->controller.'Controller.php';
}
?>
【讨论】: