【问题标题】:PHP MVC (no framework), should I be calling a lot of methods in my controller or model?PHP MVC(无框架),我应该在我的控制器或模型中调用很多方法吗?
【发布时间】:2010-11-02 02:38:50
【问题描述】:

我一直致力于在 PHP 中创建自己的 MVC 应用程序,我在网上看到了很多关于应该如何设置的不同意见。当然,我知道似乎有一种通用的“它是 MVC,它就是你所创造的”方法,但我遇到了 2 个看似相互矛盾的观点。

我的应用程序的一些背景知识:我使用 smarty 作为我的演示者和面向对象的方法。看起来很简单,但我正试图弄清楚无处不在的“什么是模型”问题。

如果我看一些教程和框架,他们似乎将模型严格地视为从抽象类继承 DAL 方法的类,由于您的数据需求与对象不同,因此在类本身中定义了一些额外的反对。例如,我可能会看到类似 $productModel->get(5) 的东西,它从数据库中返回一个包含 5 个产品的数组。那么如果我需要查询多个模型呢?我是否将所有数据存储在控制器或数组中并将其传递给视图?那么如果我动态地调用我的控制器,我怎样才能持久化渲染视图所需的控制器特有的数据呢?这似乎很糟糕,尤其是因为我必须传入诸如“controllerName”、“controllerData”之类的东西,并且我的 View::render() 方法会因参数而变得非常臃肿,除非我传入控制器本身。也许我在这里遗漏了一些东西。

假设我想创建一个查询用户表的登录。登录是一个模型或一个控制器,这取决于我在网上看到的某些实现。一些实现(我将调用此方法 1)使用方法 login() 创建一个 LoginController,它可能会比较 $_POST 和从用户模型实例 $user->get(1) 返回的内容,以查看用户是否经过验证.或者 login() 可能是默认控制器中的一个方法。另一方面,更类似于 Joomla 方法的实现(实现方法 2)将创建一个登录模型并在其中声明所有操作。然后,需要分配给视图的任何数据都将从这些方法返回。所以 login->login() 实际上会检查帖子,看看是否有匹配等。此外,用户模型可能会在该模型方法中实例化。

我对1的感受:控制器很胖。此外,控制器存储从模型中提取的数据或传入一万个变量。这似乎与模型应该将数据传递给控制器​​应该视而不见的视图的想法不符。另外,假设我想将由特定控制器处理的特定模型中的所有内容包装在外部模板中。我必须在与此模型接口的控制器功能中复制此模板设置代码。这似乎效率很低。

我对 2 的感受:它不适用于具有不是模型方法的操作。如果我想进入我的站点根目录,我必须创建一个索引模型或一些看起来有点过分的东西,以便有一个将数据传递给视图的模型。此外,这似乎不是一种非常流行的方法。但是,我更喜欢它,因为我可以只执行 View::render(mymodel->func()) 并确保数据将以我喜欢的方式传回,而不必用代码来破坏我的控制器将一千个查询结果合并在一起。

我已经经历了太多关于这个的宗教争论,想知道你们的想法。

【问题讨论】:

  • 这属于programmers.stackexchange.com 恕我直言

标签: php model-view-controller smarty design-patterns homebrew


【解决方案1】:

我过去也构建了自己的框架,所以我知道你正在经历什么。我听说过“建立胖模型”的说法,我同意这一点——只要主要目标是返回数据。我认为控制器是“霸王”,因为它操纵数据并指示它应该去哪里。

对于登录控制器,我可能会创建类似...

发布 URI:http://example.com/login/authenticate

LoginController extends ParentController {
  public function authenticate() {
    $credential_model = $this->getModel('credentials');
    // Obviously you should sanitize the $_POST values.
    $is_valid = $credential_model->isValid($_POST['user'], $_POST['email']);
    $view = $is_valid ? 'login_fail.php' : 'login_success.php';
    $data = array();
    $data['a'] = $a;
    // .. more vars
    $this->view->render($view, $data);
  }
}

在我看来,数据应该始终来自模型 -> 控制器 -> 视图,因为它最有意义(数据、操作、输出)。视图应该只能访问控制器提供的内容。

至于这个……

那么,如果我动态调用我的控制器,我如何才能持久保存渲染视图所需的控制器独有的数据?

好吧,我想您正在构建一个“基础”或“父”控制器,它会被您动态调用的控制器扩展。这些子控制器可以具有渲染视图所需的属性——老实说,我需要一个示例才能更进一步。

希望这会有所帮助。如果您提出更具体的问题,我可能会给出更深思熟虑的意见。

【讨论】:

  • 从本质上讲,控制器由前端控制器实例化,前端控制器将 a/b/c 转换为 AController、BModel、CAction 之类的东西。我可能会让 MyActionController 以不同的方式对待像 myaction/x/y/z 这样的 url,例如,y 可能是模型。我正在使用多个控制器(是的,从抽象控制器类继承方法和成员)来处理不同的格式。主要问题是,当我对这些控制器进行编码时,我是想从模型中获取数据、存储数据并将其传递给视图,还是将模型中的对象直接返回给视图渲染方法?
  • 该模型应该是一个 DAL 包装器还是应该是真正“执行”应用程序操作的模型?我看到了所有这些公理的“将应用程序和业务逻辑放入模型”语句,但我没有看到任何真实的例子。基本上,我想知道我应该去 C->M->C->V 还是 C->M->V (在第一个示例中,数据是由控制器从许多不同的模型函数调用中处理和聚合的,并且传递给视图,或者在第二个示例中,控制器只是告诉模型方法做它的事情,模型调用依赖于这个请求的所有其他模型方法)?
【解决方案2】:

如果您正在编写自己的应用程序,我认为最好的解决方案是自己动手并找出答案。

最终,任何对您来说最有意义的东西,以及让您更容易概念化您的应用并快速添加或更改它的任何东西,都将是您的最佳选择。

如果一种方法是“错误的”,那么你会通过经验发现,而不是别人告诉你。而且您会更好地了解整个情况,并且确切地知道为什么一种方法更好。

当我用 PHP 编写自己的框架时,对我有帮助的是 CherryPy。它使面向对象的 Web 应用程序的概念如此简单明了,我非常喜欢使用它,因此我对我的 PHP 框架的基本结构进行了建模以模仿 CherryPy。

我并不是要暗示你应该学习 CherryPy。我的意思是简单、清晰和享受使用您自己的网络应用程序进行开发的过程会很长。


如果我要给出一条具体的建议,我会说尽量避免重新输入代码;编写代码以在尽可能多的情况下可重用。这不仅对您的应用有好处,而且对您将来可能编写或开发的应用也有好处。

您可以查看 Eric S. Raymond 的 Rules for Unix Programming。我认为它们绝对适用于此。

【讨论】:

  • 是的。非常真实。我认为这将归结为掷硬币。 :D
  • 哈哈哈,不错。无论哪种方式,你都会学到一些东西。希望一切顺利。
猜你喜欢
  • 2011-06-03
  • 1970-01-01
  • 2011-11-17
  • 2012-04-29
  • 2016-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-19
相关资源
最近更新 更多