通过PHP插入HTML的最佳方法是什么?

时间:2008-11-04 09:31:17

标签: php html template-engine

从“最佳实践”的角度来看,您认为使用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;
?>

11 个答案:

答案 0 :(得分:25)

如果你打算以这种方式做事,你想要将你的逻辑和设计分开,这是真的。

但是你不需要使用Smarty来做这件事。

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

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

PageLogic.php

<?php 

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

  /* Logic Goes here */


 $pageData->foo = SomeValue; 

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

Layout.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}}}

通过这种方式,您可以在模板中轻易辨别出您的潜在开发途径,而不是通过 DEFAULT 行为进行利用的门户。

答案 1 :(得分:14)

-1对于典型的歇斯底里'使用[我最喜欢的模板系统]而不是!'帖子。每个PHP帖子,即使本机PHP答案是单行的,也总是退化到这里,正如每个单行JavaScript问题最终都充满了“使用[我最喜欢的框架]而不是!”。这很令人尴尬。

说真的,我们知道关于分离业务逻辑和表示问题的。您可以在任何模板系统中执行此操作 - 或执行此操作 - 无论是PHP,Smarty还是完全不同的模板。没有一定的思考,没有模板系统可以神奇地区分你的顾虑。

(事实上,一个过于严格的模板系统最终可能会导致您必须编写纯粹呈现的辅助代码,使您的业务逻辑变得混乱。这不是一个胜利!)

要回答被问到的问题,第一个例子没问题,但由于缩进不好而很难阅读。请参阅monzee的示例以获得更易读的方式;您可以使用:notation或{} s,无论您喜欢哪种,但可读性的重要一点是将HTML和PHP保持为一个“格式良好”的缩进层次结构。

最后的请求:记住htmlspecialchars()。每次纯文本需要进入网页时,必须使用,或者全部使用XSS。我知道这个问题与此没有直接关系,但每次我们发布包含&lt; ?php echo($ title)?&gt;或者没有转义的等效框架,我们鼓励大多数PHP应用程序已经成为安全灾难区域的延续。

答案 2 :(得分:7)

最重要的考虑因素是将逻辑与演示分开 - 较少的耦合将使未来的变化更加直接。

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

答案 3 :(得分:4)

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

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

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

更详细的语法使条件块比使用大括号更容易匹配。

答案 4 :(得分:2)

最好通过使用模板引擎从演示文稿(HTML)中完全分离您的逻辑(PHP代码)。

将PHP插入HTML非常容易,但它很快就会变得混乱,而且很难维护。这是非常快速和非常脏的方法......

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

答案 5 :(得分:1)

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

答案 6 :(得分:1)

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

template.inc:

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

的index.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);
?>

答案 7 :(得分: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可以被看作是这样改变的,你的设计师可以理解它,而不必仔细查看你的代码,试图从不同的地方把零碎的东西放在一起有机会看到她在做什么。另一方面,您可以对逻辑进行更改,而无需担心它在页面上的外观。你很可能也会减少错误,因为你的代码会很紧凑,而且可以读取。

答案 8 :(得分:1)

我希望在我第一次开始使用PHP时就已经知道了:保持繁重的程序代码尽可能远离HTML输出。这样他们就可以保持大型,相当连续,可读的块。

我发现这样做的最好方法是先创建一个静态HTML文件 ,也许还有一些假数据,这样我就可以找到正确的设计,然后编写PHP代码得到输出的动态部分并将它们粘合在一起(你如何做到这一点取决于你 - 你可以像其他人所建议的那样使用Smarty)。

答案 9 :(得分:1)

如果必须以任何方式使用花括号。不要用PHP回显HTML。

答案 10 :(得分:0)

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

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