1

我一直致力于在 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()) 并确保数据将以我喜欢的方式传回,而不必用代码来破坏我的控制器将一千个查询结果合并在一起。

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

4

2 回答 2

4

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

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

发布 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);
  }
}

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

至于这个……

然后,如果我动态调用我的控制器,我如何才能保留渲染视图所需的控制器独有的数据?

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

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

于 2010-11-02T03:16:19.490 回答
1

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

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

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

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

我并不是要暗示你应该学习 CherryPy。我的意思是简单、清晰和享受使用您自己的 Web 应用程序进行开发会大有帮助。


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

您可以查看 Eric S. Raymond 的Unix 编程规则。我认为它们绝对适用于这里。

于 2010-11-02T03:27:56.463 回答