29

从“最佳实践”的角度来看,您认为使用 PHP 插入 HTML 的最佳方式是什么。目前我使用以下方法之一(主要是后者),但我很想知道您认为哪种方法最好。

<?php
  if($a){
?>
[SOME MARKUP]
<?php
  }
  else{
?>
[SOME OTHER MARKUP]
<?php
  }
?>

反对:

<?php
  unset($out);
  if($a) $out = '[SOME MARKUP]';
  else $out = '[OTHER MARKUP]';
  print $out;
?>
4

11 回答 11

27

如果你打算那样做,你想把你的逻辑和设计分开,真的。

但是您不需要使用 Smarty 来执行此操作。

优先级是关于心态。我看到人们在 Smarty 中做令人震惊的事情,最终变成人们Smarty 中开发网站,然后一些明亮的火花将决定他们需要在 Smarty 中编写模板引擎(永远不要低估愚蠢想法的潜力)。

如果您将代码分成两部分并强迫自己遵守标准,那么您将获得更好的性能。

页面逻辑.php

<?php 

  $pageData = (object)(array());  // Handy trick I learnt. 

  /* Logic Goes here */


 $pageData->foo = SomeValue; 

 ob_start(); 
 require("layout.php"); 
 ob_end_flush();

布局.php

 <html>
   <!-- etc -->
   <?php for ( $i = 1; $i < 10; $i++ ){ ?>
    <?php echo $pageData->foo[$i]; ?>
   <?php } ?>
   <!-- etc -->
</html>

PHP 是作为模板引擎编写的,因此在评估是否需要深入研究 Smarty 之前,您至少应该尝试将其用于其设计任务。


此外,如果您决定使用模板引擎,请尝试使用默认转义 HTML 的引擎,然后您“选择退出”而不是“选择加入”。你会为自己省去很多 XSS 的麻烦。Smarty 在这方面比较薄弱,正因为如此,里面写了很多内容朴素的模板。

{if $cond}
    {$dangerous_value}
{else}
    {$equally_dangerous_value}
{/if}

通常是 Smarty 模板的运行方式。问题是 $dangerous_value 可以是任意 HTML,这只会导致糟糕的编码实践,到处都是无法追踪的意大利面条代码。

您考虑的任何模板语言都应满足此问题。例如:

{$code_gets_escaped} 
{{$code_gets_escaped_as_a_uri}}
{{{$dangerous_bare_code}}}

通过这种方式,您的潜在利用途径在模板中很容易辨别,而利用途径是默认行为。

于 2008-11-04T11:11:33.783 回答
14

-1 代表典型的歇斯底里“改用 [我最喜欢的模板系统]!” 帖子。每个 PHP 帖子,即使原生 PHP 答案是单行的,也总是退化成这样,就像每个单行 JavaScript 问题最终都充满了“改用 [我最喜欢的框架]!”。太丢脸了。

说真的,我们知道分离业务逻辑和表示关注点。你可以在任何模板系统中这样做——或者不这样做——无论是 PHP、Smarty 还是完全不同的东西。没有经过大量思考的模板系统可以神奇地分离您的关注点。

(事实上​​,限制性太强的模板系统最终可能会导致您不得不编写纯粹呈现的辅助代码,从而使您的业务逻辑因呈现问题而变得混乱。这不是胜利!)

要回答所提出的问题,第一个示例还可以,但由于缩进不好,很难阅读。请参阅 monzee 的示例以获得更易读的方式;您可以使用 : 表示法或 {},无论您喜欢哪一种,但重要的是保持您的 HTML 和 PHP 作为一个单一的、“格式良好”的缩进层次结构。

最后一个请求:记住 htmlspecialchars()。每次纯文本需要进入网页时,都必须使用这个,否则就是XSS。我知道这个问题与此没有直接关系,但是每次我们发布包含 < ?php echo($title) ?> 的示例代码或没有转义的等效框架时,我们都在鼓励继续安全灾难区域大多数 PHP 应用程序已经成为。

于 2008-11-04T11:40:02.493 回答
7

最重要的考虑是保持逻辑与表示分离 - 更少的耦合将使未来对两者的更改更加直接。

您甚至可能要考虑使用某种模板系统,例如smarty

于 2008-11-04T09:34:32.857 回答
4

对于这样一个非常简单的情况,使用 PHP 作为模板就可以了。但是,如果您超越了简单的逻辑(您很可能会这样做),那么使用模板引擎是一个好主意。

在默认使用 PHP 视图脚本的 Zend Framework 中,推荐的方法是这样的:

<?php if ($a) : ?>
    [MARKUP HERE]
<?php else : ?>
    [SOME MORE MARKUP]
<?php endif ?>

与使用大括号相比,更详细的语法使得一目了然地匹配条件块要容易得多。

于 2008-11-04T09:58:24.867 回答
1

两者都不。使用智能。通过将内部逻辑与显示逻辑分开,您将构建更易于维护的代码。(不要走 PHPLib 的旧模板系统尝试完全分离 PHP 和 HTML 的路径——它需要显示逻辑与您的核心业务逻辑混合在一起,并且非常混乱。)如果您绝对必须在 PHP 代码中生成 HTML 片段,使用第二种方法,但将变量传递给 Smarty。

于 2008-11-04T09:37:28.887 回答
1

最好使用模板引擎将逻辑(PHP 代码)与演示文稿(HTML)完全分开。

将 PHP 插入 HTML 既快速又容易,但很快就会变得混乱,并且很难维护。这是一种非常快速且非常肮脏的方法......

至于 PHP 中可用的所有模板引擎中哪个更好,请参阅以下问题,例如:

于 2008-11-04T09:48:06.730 回答
1

如果模板引擎看起来很麻烦,您可以制作自己的穷人模板引擎。这个例子肯定需要改进,并不适合所有任务,但可能适合较小的站点。只是给你一个想法:

模板.inc:

<html><head><title>%title%</title></head><body>
%mainbody%
Bla bla bla <a href="%linkurl%">%linkname%</a>.
</body></html>

索引.php:

<?php
$title = getTitle();
$mainbody = getMainBody();
$linkurl = getLinkUrl();
$linkname = getLinkName();
$search = array("/%title%/", "/%mainbody%/", "/%linkurl%/", "/%linkname%/");
$replace = array($title, $mainbody, $linkurl, $linkname);
$template = file_get_contents("template.inc");
print preg_replace($search, $replace, $template);
?>
于 2008-11-04T09:57:57.007 回答
1

如果您不使用框架或使用没有自己的模板系统的框架,Smarty 是可以的。

否则大多数 PHP 框架和年轻一代的 CMS 都有自己的模板系统。

一般来说,模板系统的想法是让文件几乎只包含 HTML(视图/模板文件)和只包含数据或业务逻辑的文件(模型或控制器文件)。

模板文件可能看起来像这样(来自 SilverStripe 的示例):

<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head>
        <% base_tag %>
        $MetaTags
        <link rel="stylesheet" type="text/css" href="tutorial/css/layout.css" />
    </head>
    <body>
        <div id="Main">
            <ul id="Menu1">
                <% control Menu(1) %>
                <li class="$LinkingMode">
                    <a href="$Link" title="Go to the &quot;{$Title}&quot; page">$MenuTitle</a>
                </li>
                <% end_control %>
            </ul>
            <div id="Header">
                <h1>$Title</h1>
            </div>
            <div id="ContentContainer">
                $Layout
            </div>
            <div id="Footer">
                <span>Some Text</span>
            </div>
        </div>
     </body>
</html>

您可以看到,在将页面发送到客户端之前,将插入数据的地方只插入了一些非 HTML 代码片段。

然后,您的代码可以(简化)看起来像:

<?php
  unset($out);
  if($a) $out = '[SOME CONTENT TO INSERT INTO THE TEMPLATE]';
  else $out = '[SOME ALTERNATIVE CONTENT]';
  templateInsert($out);
?>

关于它的好处:您的 HTML 可以被视为这样并可以这样进行更改,您的设计人员可以理解它,并且不必查看您的代码试图将来自不同地方的点点滴滴拼凑在一起,而没有任何机会看看她在做什么。另一方面,您可以对逻辑进行更改,而不必担心它在页面上的外观。您很可能还会犯更少的错误,因为您的代码将是紧凑的,因此是可读的。

于 2008-11-04T10:05:47.550 回答
1

当我第一次开始使用 PHP 时,我希望我知道:让你的繁重程序代码尽可能远离你的 HTML 输出。这样,它们都保持在大的、相当连续的、可读的块中。

我发现这样做的最好方法是首先制作一个静态 HTML 文件可能包含一些假数据,这样我就可以四处寻找并正确设计,然后编写 PHP 代码来获取输出的动态部分并将它们粘合起来两者一起(你如何做这部分取决于你 - 你可以像其他人建议的那样与 Smarty 一起做)。

于 2008-12-02T00:56:44.353 回答
1

如果您必须这样做,请使用花括号。不要用 PHP 回显 HTML。

于 2009-03-02T18:18:45.900 回答
0

不要使用 smarty - PHP 本身就是一个模板系统。考虑使用以下语法:

<?php if($a):?>
[SOME MARKUP]
<?php else: ?>
[SOME OTHER MARKUP]
<? endif; ?>
于 2008-11-04T10:13:59.203 回答