我使用术语“部分”来指代在许多视图中重复的一小部分演示代码。例如,侧边栏。在 vanilla PHP 中,业务和表示逻辑混合在一起,包括一个侧边栏是没有问题的:
if($someCondition) {
include('sidebar.php');
}
但是,在 MVC 设计模式中,表示逻辑必须保留在视图中,而业务逻辑必须保留在控制器中。如果我希望无条件地包含一个部分,那么这是没有问题的,因为我可以include('sidebar.php')
在我看来。但是,我不能再有条件地这样做,因为如果我认为逻辑被禁止的话。
我尝试了许多解决方案,但它们都有问题。我目前正在使用解决方案 2:
解决方案 1
在我的视图类中创建一个包含函数,它可以有条件地包含来自我的控制器的内容。所以在我的控制器中,我可以有以下逻辑:
if($someCondition) {
$this->view->include('sidebar.php');
}
$this->view->show('index.php');
问题: sidebar.php 需要在特定点包含到 index.php 中,这需要视图对象上的 include 方法进行某种解析。
解决方案 2
将部分控件移出视图并将它们放入控制器中:
if($someCondition) {
$this->view->show('header.php', 'sidebar.php', 'index.php', 'footer.php');
}
else {
$this->view->show('header.php', 'index.php', 'footer.php');
}
问题:将大部分表示逻辑移动到控制器领域。对我来说,决定是否包含标题似乎更自然。事实上,我能找到的每个 PHP MVC 教程都有部分在视图而不是控制器的控制下。
解决方案 3
复制视图并更改克隆,使其包含侧边栏。然后我可以有条件地在控制器中加载一个或另一个:
if($someCondition) {
$this->view->show('indexWithSidebar.php');
}
else {
$this->view->show('index.php');
}
问题:代码重复。考虑一下如果我有 2 个需要有条件加载的侧边栏会发生什么。然后我需要index.php, indexWithSidebar1.php, indexWithSidebar2.php, indexWithSidebar1And2.php
. 这只会在每种情况下变得更糟。请记住,将侧边栏作为部分取出的全部目的是为了避免复制它,而这种方法似乎违背了这一点。
这些解决方案中的任何一个都是“正确”的解决方案吗?如果是,我该如何克服他们的问题?那里有更好的方法吗?