PHP中的MVC,不带;“魔术”;
假设我有一个PHP模型视图控制器框架,它映射了一个地址,比如PHP中的MVC,不带;“魔术”;,php,design-patterns,model-view-controller,Php,Design Patterns,Model View Controller,假设我有一个PHP模型视图控制器框架,它映射了一个地址,比如http://example.com/admin/posts/edit/5添加到一个看起来像 Posts_Controller::editAction($id) 在文件/admin/controllers/posts.php 现在,我看到的许多现有PHP框架都可以通过类似于 $module = Router::getModule(); // "admin" $controller = Router::getCont
http://example.com/admin/posts/edit/5
添加到一个看起来像
Posts_Controller::editAction($id)
在文件/admin/controllers/posts.php
现在,我看到的许多现有PHP框架都可以通过类似于
$module = Router::getModule(); // "admin"
$controller = Router::getController(); // "posts"
$action = Router::getAction(); // "edit"
$params = Router::getParams(); // array(5)
$controller_file = "/".$module."/controllers/".$controller.".php";
$controller_classname = ucfirst($controller)."_Controller";
$method = $action."Action";
require_once $controller_file;
$controller_obj = new $controller_classname();
call_user_func_array(array($controller_obj,$method),$params);
对我来说,这闻起来很难闻,似乎太“神奇”:我不相信您应该能够基于字符串动态创建类,然后调用指定为字符串的方法
我也看到过使用反射来调用动作的替代方案,这也很糟糕
现在想象一下,我有一个更大的、模块化的CMS,它是基于一个类似的MVC框架构建的,在DB中有一个表,用于每个“页面”类型:博客、静态、相册等。。。我认为这方面的实现类似于我前面的示例
我是唯一一个认为这不好的人吗?如果没有,是否应该有一个设计模式来覆盖这种情况
澄清:
是否有一些好的方法将包含模块、控制器、操作和参数信息的查询映射到
更好的是:在没有反射的情况下,如何在C#或Java中实现这一点?我可以将字符串连接到文件位置。这将由某种工厂模式来处理,PHP只是做了一些很好的语法糖,以避免工厂模式周围的所有实现。我认为这一点也不神奇,它只是利用了语言。这将由某种工厂模式来处理,PHP只是做了一些很好的语法糖来避免工厂模式周围的所有实现。我认为这一点也不神奇,它只是利用了语言。对于我所做的大部分工作,MVC框架似乎过于臃肿 我更喜欢使用模板引擎,比如smarty()
您仍然可以获得相同的代码和表示分离。我发现它创建了更整洁的代码组织,您可以在其中管理所有文件和目录结构。代码可以按逻辑分组,而不是按页面分组。对于我所做的大部分工作,MVC框架似乎过于臃肿 我更喜欢使用模板引擎,比如smarty()
您仍然可以获得相同的代码和表示分离。我发现它创建了更整洁的代码组织,您可以在其中管理所有文件和目录结构。代码可以按逻辑分组,而不是按页面分组。听起来你的问题在于ORM magic而不是MVC,它只是一个麻瓜。听起来你的问题在于ORM magic而不是MVC,它只是一个麻瓜。我不知道你看过哪些框架。到目前为止,我使用的(CodeIgniter和Yii)确实很神奇,但有安全措施。例如,所有控制器都需要从控制器类扩展,因此您不能实例化任何类,只能实例化一个控制器。对于CodeIgniter,建议将不应通过浏览器访问的所有控制器方法声明为私有。Yii将这一点提升到了另一个层次,要求所有这些方法都以“action”开头(在您的示例中是“actionEdit”),因此您确实无法从外部调用任意方法
我发现,当一个团队中有多个开发人员时,所有这些魔法都非常有用,因为它确保人们遵守规则,并且更容易了解彼此的代码并了解发生了什么。如果不强制执行这些约定,您必须花时间在浏览器中跟踪哪个链接指向何处,然后深入PHP代码以找到它的去向。在C#或Java中,像PHP这样的松散语言(没有严格的类型、首次使用时声明的变量、动态数组等)可能会把它弄得一团糟。在PHP中,它是执行顺序的语言,是框架的工作。我不知道您看过哪些框架。到目前为止,我使用的(CodeIgniter和Yii)确实很神奇,但有安全措施。例如,所有控制器都需要从控制器类扩展,因此您不能实例化任何类,只能实例化一个控制器。对于CodeIgniter,建议将不应通过浏览器访问的所有控制器方法声明为私有。Yii将这一点提升到了另一个层次,要求所有这些方法都以“action”开头(在您的示例中是“actionEdit”),因此您确实无法从外部调用任意方法
我发现,当一个团队中有多个开发人员时,所有这些魔法都非常有用,因为它确保人们遵守规则,并且更容易了解彼此的代码并了解发生了什么。如果不强制执行这些约定,您必须花时间在浏览器中跟踪哪个链接指向何处,然后深入PHP代码以找到它的去向。在C#或Java中,像PHP这样的松散语言(没有严格的类型、首次使用时声明的变量、动态数组等)可能会把它弄得一团糟。在PHP中,是语言强制执行顺序,是框架的工作。事实上,这里有两个问题
abstract class Message {
// has a bunch of info about the current program state as properties,
// retrieved from e.g. $_POST or the db,
// and ways to retrieve that info automatically as methods named after the channel
// they pull information from,
// the constructor is responsible for using these methods
// so they should be protected
}
interface Action {
// now we know enough about a message to handle it in an abstract way,
// no array mapping etc.
function doSomething($Message);
}
/** do this up the same way it exists in the database */
abstract class ModelObject {
public $fields = array();
// I am a linked list
public $next = NULL;
public $prev = NULL;
// constructor that takes a primary key as an argument and pulls stuff
// from the DB with it
}
/** this has a predictable name known to the Main application controller */
hook_do_stuff() {
$state = new DoStuffMessage();
$user = new User(); // User is a ModelObject
// maybe there is even an Admin ModelObject that can use $user in its constructor?
// decide how to handle things in an abstract way here,
// maybe even run tests on the URL as it is now just another piece of
// program state information
}