我正在尝试理解并找出在自定义框架中切换控制器的好方法。以下示例是我目前正在考虑的,为了演示目的而简化,但如果有更好的方法,我会非常感谢一些专家建议吗?
class BaseController() {
function __construct() {
$this->model = new ModelFactory();
$this->view = new View();
if(isset($_SERVER['QUERY_STRING'])) {
list($controller, $action) = explode('=', $_SERVER['QUERY_STRING']);
self::process($controller);
}
}
public function process($controller) {
switch($controller) {
case 'user':
$user = new UserController($action);
break;
case 'forum':
$forum = new ForumController($action);
break;
default:
// use base controller
switch($action) {
case 'contact':
$this->view->load($action);
break;
}
}
}
}
// inside UserController.php
switch($action) {
case 'register':
break;
case 'login':
break;
}
// inside ForumController.php
switch($action) {
case 'new_thread':
break;
case 'edit_post':
break;
}
答案 0 :(得分:3)
这实际上是一个部分答案,希望能给你一些好的指示。我相信有更好答案的人会来。
您示例中的BaseController
可能名称错误。你拥有它使它看起来更像一个控制器工厂,而不是所有其他控制器类可能派生的基本控制器。看起来这更像是一个“路由”类,所以你应该考虑给它一个更合适的名字。
如果您希望框架用户使用自定义操作创建自定义控制器:
a)你肯定想要为所有控制器类创建至少一个接口来实现。称之为IController
或类似的东西。这将在下一步中使用。
b)你必须满足于使用字符串作为类名创建对象。 “Route”处理程序类中的IE $controllerObject = new $controller();
。原因是要运行的控制器和操作名称直接来自请求URL。这部分有别名的方法,但这完全是另一个问题。 不忘记验证和/或列入从客户端传入的这些“控制器”类名称。要验证:使用PHP函数class_exists($controller)
然后如果true
,请检查以确保控制器类使用PHP的内置IController
实现class_implements($controller)
。只有然后才能$controllerObject = new $controller();
实际创建控制器对象。
您的“路由”process
方法会变得更像(并且请记住这是非常简化示例):
public function process($controller, $action) {
if (!class_exists($controller)) {
throw new Exception('Controller class does not exist.');
}
if (!in_array("IController", class_implements($controller))) {
throw new Exception('Route is not a valid controller.');
}
if (!method_exists($controller, $action)) {
throw new Exception('No such action for requested controller.');
}
$ctrl = new $controller();
return $ctrl->$action();
}
c)不要让你的控制器声明任何方法(即使用$action
可能的值命名)你不希望客户端使用上面的设计模式直接执行。希望您的框架用户也能理解这一点。请务必在内部正确记录其工作原理,以便让您的框架用户了解。
当然还有更多的方法,但这取决于你 - 框架设计师。此外,该动作应该在使用什么“视图”中具有最终发言权。如果操作没有明确说明要使用的视图,则可以设置默认值。但同样,这将是另一个问题。
答案 1 :(得分:0)
你真的应该首先阅读MVC实际上是什么。我建议从福勒的GUI Architectures开始。因为有一件事是非常肯定的 - 你所拥有的不是它。
看起来,你所谓的BaseController
,实际上是在处理路由。它是用户的请求URL,并包含基于您从所述URL检索到的内容的文件。这既不是OOP也不是程序编程。你在那里所拥有的是non-structured programming。
而不是这种疯狂,你应该创建一个单独的类,为你的应用程序实现路由机制。根据您使用所述结构提取的数据,您应该启动特定的控制器实例,并在其上调用方法。
类似的东西:
$request = new Request('QUERY_STRING');
$router = new Router;
$router->import('/path/to/routing/config.file');
$router->route( $request );
$klass = $request->getParameter('controller');
if (class_exists( $controller ))
{
$command = $request->getMethod() . $request->getParameter('action');
}
else
{
$klass = 'Error';
$command = 'getMessage';
}
$controller = new $klass;
$controller->{$command}( $request );
这当然是一个非常简化的版本。 MVC模式旨在为大型项目带来一些订单。如果你用它来创建像一个简单的博客/商务卡网站,它似乎是一种矫枉过正(假设页面没有增长)。