如何不将表现与逻辑混合?

时间:2011-01-19 20:41:33

标签: php

我使用PHP相当多,每当我在某个论坛上看到“PHP-hate”主题,甚至在这里进行与PHP相关的讨论时,我通常会看到以下内容:

  

PHP过于混乱/草率/糟糕,因为你有一个纠结的演示文稿和逻辑网。

然后我看到PHP-Defenders回复上述某些版本的说法并不一定正确。我开始思考“这怎么可能......?”和“什么算是混合演示与逻辑?”我无法理解,所以现在我在这里。

以下哪项是最佳做法?或者有更好的方法,我不知道?

<?php
    if(!function()) {
        echo '<div id="results">The result is a lie.</div>';
        }
?>

或者

<div id="results">
    <?php
        if(!function()) {
            echo 'The result is a lie.';
            }
    ?>
</div>

我知道上面的例子看起来并不是什么大不了的事,但在浏览了我的网络应用程序后,我意识到它有点混乱(因为我混合了HTML和PHP),所以我希望这是一个很好的发展方式,同时保持良好和整洁。

7 个答案:

答案 0 :(得分:11)

也许你想看看模板引擎,比如聪明。这可以为你分开。

链接:http://www.smarty.net/

一些(希望平衡的)增加看到下面相当大的评论部分:

似乎有很多关于聪明的讨论。据我所知,这里有两个额外的阵营,

有人说:模板引擎,好吧,但聪明不是最好的;使用(在此处插入您的选择)。 例如:twig或dwoo。

另一个人说:不要使用单独的模板引擎!因为PHP完全有能力做到这一点。评论中的示例包括:

  

使用Zend_View和Savant

答案 1 :(得分:2)

考虑逻辑和演示,其中逻辑是一种电插座,演示是灯泡。现在你家里可以有多个插座,有些插座有不同尺寸的插座。你也可以买一堆不同颜色的灯泡,一些便宜的灯泡,一些昂贵的灯泡。关键是一个灯泡可以插入一个或多个袜子,一个插座可以接受多个灯泡,但一次只能将一个灯泡与一个灯泡匹配。

因此,如果你有一个非常好的灯泡(或非常好的html模板),你希望能够将灯泡移动到你需要的地方(或应用相同的逻辑)。如果有一天你决定要使用蓝色灯泡,你只需更换灯泡,就不必安装一个全新的电源插座来改变颜色。

回到逻辑和演示文稿,如果您遇到网页上有表单的常见情况,有时您会在用户第一次加载页面时显示该表单,有时您希望在用户之后显示该表单填写了一些输入,但可能有错误或缺少信息。在这种情况下,逻辑将不执行任何操作,只显示表单,或尝试处理表单,找到错误,然后显示显示错误的表单。

当然,您可以在同一个文件中使用混合逻辑和演示文稿来执行此操作,但是当多个人开始编辑您的脚本时会发生什么?也许剧本破了,他们不知道该怎么做,所以他们会注意到一些重要的部分,让它再次运作。这就像有人要更换灯泡然后决定重新连接你的灯开关。但有时当你遇到布线不良时,没有其他方法可以解决这个问题,问题从简单的“请更换灯泡”到“让灯泡工作”。在设计合理的系统中,组件以合理的方式隔离,通常更容易修复。

换句话说,混合逻辑和演示就像使用裸线硬连接灯泡,然后将电线连接到电源而不需要断路器以确保安全。

答案 2 :(得分:1)

第二个例子更好。

避免将表示与逻辑混合的最简单方法是使用像Symfony或CakePHP这样的MVC框架。这些允许您将数据(模型)与逻辑(控制器)和表示(视图)分开。

另一个答案是好的:使用模板。模板几乎总是MVC框架的一部分。

答案 3 :(得分:0)

您可以在包含的文件或页面顶部定义帮助方法:

<?php
function result_if_good()
{
    if (!function()) {
       return 'The result is a lie.';
    }
}
?>

然后在其他地方,在您的HTML中:

<div id="results"><?php echo result_if_good();?></div>

将所有逻辑都排除在演示文稿之外。

答案 4 :(得分:0)

如果您希望在逻辑与界面之间实现真正的分离,则应该查看MVC pattern

我使用MVC模式中的视图和模板的引擎来为我的视图实现干净的HTML文件

答案 5 :(得分:0)

我想,您可以尝试使用ZendFramework

答案 6 :(得分:0)

我更喜欢脚本在需要时输出HTML和javascript的情况。换句话说,更像是(在伪python中):

#Primitives
def htmlheader(title):
    return "<html><head><title>%title</title></head>" % title 

def body:
    return "<body>"

def para(content):
    return "<p>%content</p>" %  content

def htmlend:
    return "</body></html>"

#New file: View

print htmlheader()
print body()
print para("This is my paragraph")
print para("Hello, %salatation %lastname" % dbresult.salutation, dbresult.lastname)
print htmlend()

PHP受到被&lt;&gt;包围的困扰,这已经很难阅读了。

YMMV

使用原语来输出实际的html,然后可以创建一个控制器层,它只是将纯数据传递给视图。更多pseudoPython:

#ViewController

db = dbconnect("host", "user", "password");

view.mainbody.show(getCurrentNews(db))
view.header.show(getTopHeadLines(db))
if (user.isLoggedIn):
  view.footer.userNavigation()
else:
    view.footer.showDefault()
view.render