PHP中的MVC,不带;“魔术”;

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

假设我有一个PHP模型视图控制器框架,它映射了一个地址,比如
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中有一个表,用于每个“页面”类型:博客、静态、相册等。。。我认为这方面的实现类似于我前面的示例

我是唯一一个认为这不好的人吗?如果没有,是否应该有一个设计模式来覆盖这种情况

澄清: 是否有一些好的方法将包含模块、控制器、操作和参数信息的查询映射到

  • 要包括的文件
  • 要实例化的类
  • 调用“”的方法
  • 尽可能使用aslittle的“魔力”(字符串到类或-到方法或反射)


    更好的是:在没有反射的情况下,如何在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中,是语言强制执行顺序,是框架的工作。

    事实上,这里有两个问题

  • PHP作为一种语言在这里是否正确使用
  • 这段代码的逻辑太“神奇”了吗
  • 作为一名PHP开发人员和软件工程师,我可以提出我的观点,主要是基于一些MVC框架开发web应用程序

    1) 每种语言都有自己的语法,或多或少提供了表达能力。我同意,为了可读性和简单性,不应该在每一行代码上都使用一种语言的所有功能。但在这种情况下,在设计和实现MVC核心的地方,我认为没有理由不使用它们,特别是在最终用户(appl
     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
     }