簡體   English   中英

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

[英]What is the best way to insert HTML via PHP?

從“最佳實踐”的角度來看,您認為使用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;
?>

如果你打算以這種方式做事,你想要將你的邏輯和設計分開,這是真的。

但是你不需要使用Smarty來做這件事。

優先考慮的是心態。 我看到人們在Smarty中做了令人震驚的事情,最終變成了人們 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對於典型的歇斯底里'使用[我最喜歡的模板系統]來代替! 帖子。 每個PHP帖子,即使本機PHP答案是單行的,也總是退化到這里,正如每個單行JavaScript問題最終都充滿了“使用[我最喜歡的框架]而不是!”。 這讓人很難堪。

說真的,我們知道將業務邏輯和表示問題分開。 你可以在任何模板系統中做到這一點 - 或者這樣做 - 無論是PHP,Smarty還是完全不同的東西。 沒有一堆思考,沒有模板系統可以神奇地區分你的顧慮。

(事實上​​,一個過於嚴格的模板系統最終可能會導致您必須編寫純粹表現性的輔助代碼,使您的業務邏輯變得混亂。這不是一個勝利!)

為了回答所提出的問題,第一個例子沒問題,但由於壓痕不好而很難閱讀。 請參閱monzee的示例以獲得更易讀的方式; 您可以使用:notation或{} s,無論您喜歡哪種,但可讀性的重要一點是將HTML和PHP保持為單個“格式良好”的縮進層次結構。

最后的請求:記住htmlspecialchars()。 每次純文本需要進入網頁時, 必須使用它,或者它是全部的XSS。 我知道這個問題與此沒有直接關系,但每當我們發布包含<?php echo($ title)?>的示例代碼或沒有轉義的框架等效時,我們都鼓勵繼續安全災難區域大多數PHP應用程序已成為。

最重要的考慮因素是將邏輯與表示分開 - 較少的耦合將使未來的變化更加直接。

你甚至可能想考慮使用像smarty這樣的模板系統。

對於這樣一個非常簡單的情況,可以使用PHP作為模板。 但是,如果你超越了簡單的邏輯(並且你很可能會),那么使用模板引擎是個好主意。

在Zend Framework中,默認使用PHP視圖腳本,推薦的方法是這樣的:

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

更詳細的語法使得條件塊比使用大括號更容易匹配。

最好通過使用模板引擎從演示文稿(HTML)中完全分離您的邏輯(PHP代碼)。

將PHP插入到HTML中是快速而容易的,但它很快就會變得混亂,並且很難維護。 這是一種非常快速且非常骯臟的方法......

至於PHP中可用的所有模板引擎中哪一個更好,請參閱以下問題,例如:

都不是。 使用Smarty 通過將內部邏輯與顯示邏輯分離,您將構建更易於維護的代碼。 (不要采用PHPLib舊模板系統試圖完全分離PHP和HTML的路徑 - 它需要顯示邏輯與您的核心業務邏輯混合在一起並且非常混亂。)如果您絕對必須在PHP代碼中生成HTML片段,使用你的第二種方法,但將變量傳遞給Smarty。

如果模板引擎看起來很麻煩,你可以制作自己的窮人模板引擎。 這個例子肯定會得到改進,並不適合所有任務,但對於較小的站點可能是合適的。 只是為了得到一個想法:

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);
?>

如果您沒有使用框架,或者當您使用的框架沒有自己的模板系統時,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可以被看作是這樣改變的,你的設計師可以理解它,而不必查看你的代碼,試圖從不同的地方把零碎的東西放在一起,沒有任何機會看看她在做什么。 另一方面,您可以對邏輯進行更改,而無需擔心它在頁面上的外觀。 你很可能也會減少錯誤,因為你的代碼會很緊湊,而且可讀。

我希望在我第一次開始使用PHP時就已經知道了:保持繁重的程序代碼盡可能遠離HTML輸出。 這樣他們都可以保持大型,相當連續,可讀的塊狀態。

我發現這樣做的最好辦法是讓靜態HTML文件首先 ,也許有一些假的數據,所以我可以閑逛,並獲得設計權,然后編寫PHP代碼來獲取輸出的動態部分和膠水他們兩者在一起(你如何做到這一點取決於你 - 你可以像其他人一樣建議使用Smarty)。

如果你必須這樣做,可以使用花括號。 不要用PHP回顯HTML。

不要使用smarty - PHP本身就是一個模板系統。 考慮使用以下語法:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM