2008-09-22 99 views
10

我正在創建一個網站,其中不同的網頁可能會根據特定的條件(即登錄或不,表格填寫或不等,等)看起來非常不同。這使得有必要在不同的時間輸出不同的html塊。保持我的PHP漂亮

但是,這樣做會讓我的php代碼看起來很可怕......它真的會與代碼的格式和「形狀」混淆。我應該如何解決這個問題?在我的腳本底部包含自定義「html轉儲」功能?同樣的事情,但包括? Heredocs(看起來不太好)?

謝謝!

回答

25

不要驚慌,每個新鮮的Web程序員都面臨着這個問題。

您必須將您的程序邏輯與顯示器分開。首先,請嘗試使用兩個文件爲每個網頁自己的解決方案,使:

  • 一個只有PHP代碼(無HTML)充滿變數
  • 另一個HTML和很少的PHP:這是你的頁面設計

然後包括何時/何時需要它。 EG:

myPageLogic.php

<?php 

// pure PHP code, no HTML 

$name = htmlspecialchars($_GET['name']); 
$age = date('Y') - htmlspecialchars($_GET['age']); 

?> 

myPageView.php

// very few php code 
// just enought to print variables 
// and some if/else, or foreach to manage the data stream 

<h1>Hello, <?php $name ?> !</h1> 

<p>So your are <?php $age?>, hu ?</p> 

(您可能需要使用alternative PHP syntax這一個,但不要着急,使其完善。第一次,真的。)

myPage.php

<?php 

require('myPageLogic.php'); 
require('myPageView.php'); 
?> 

現在不要擔心性能問題。這不是你作爲新手的優先事項。這個解決方案是不完善的,但會幫助您解決您的編程級別的問題,並會教您基本知識。然後,一旦你對這個概念感到滿意,就買一本關於MVC模式的書(或者查看關於它的堆棧溢出條目)。那你想做什麼下一次。然後你會嘗試一些模板系統和框架,但是LATER。就目前而言,只需編碼並從一開始就學習。你可以像這樣完美地編寫一個項目,作爲一個菜鳥,沒關係。

+0

這就是我現在所做的。處理腳本中的數據,包括適當的'視圖'腳本。在視圖腳本中,我只在HTML內部回顯變量,並在必要時使用if-else和循環。 – Imran 2008-09-22 13:20:24

0

在這種情況下,我會將所有東西逐漸寫入變量或有時是數組,然後回顯變量/數組。它具有額外的優勢,即頁面始終呈現,而不是逐漸呈現。

0

我在這種情況下最終做的是構建包含HTML數據的'模板'文件,然後使用正則表達式進行解析。它使代碼保持清潔,並且更容易將代碼片斷傳遞給設計人員或其他HTML人員。

退房背後MVC編程實踐理想的Wikipedia

1

從您的問題的聲音看來,您的代碼中的邏輯和表示之間似乎沒有太多分離。在設計應用程序時,這是一個非常重要的考慮因素,因爲您目前所面臨的情況正好證明了這一點。

如果你還沒有,我會看看一些PHP模板引擎,如Smarty

4

儘量將您的內容和佈局與代碼分開。任何時候你在.php文件中寫入任何HTML,停下來想一想「這真的是屬於這裏嗎?」

一個解決方案是使用模板。看看Smarty模板系統是一個非常易於使用的選項。

+0

任何模板引擎都可以解決這個問題,而不需要MVC框架的開銷。 Smarty是最好的選擇。 – Ian 2008-09-22 08:54:46

+1

另一個模板系統(PHP本身)之上的模板系統(Smarty)原則上處於開銷狀態。我都是用XSL Transformations(http://www.w3schools.com/xsl/)Twan – Twan 2008-09-22 09:40:15

+1

這樣的技術人,認真的...... XSLT是太複雜了,絕對不需要OP所說的內容。對於初學者來說,首先需要一些XML進行轉換。 – nickf 2008-09-22 12:34:47

0

您需要一個框架。這不僅會使你的代碼更漂亮(因爲已經提到了模型 - 視圖 - 控制器模式,MVC) - 它會爲你節省時間,因爲已經爲它編寫的組件。

我推薦QCodo,它很棒;還有其他的 - CakePHP,Symfony。

0

如果這是一個大項目,框架可能是有序的。如果沒有,請創建一些模板文件,並在頁面頂部決定要包含哪個模板文件。

例如

if ($_SESSION['logged_in']) 
    include(TPL_DIR . 'main_logged_in.tpl'); 
else 
    include(tPL_DIR . 'main.tpl'); 

只是一個簡單的例子

以上..你是固定的症狀,而不是問題,因爲提到
0

..

你需要的是邏輯的分離和介紹。這可以通過某種mvc框架來完成。即使你不想全部採用mvc框架..一個模板引擎是必須的,至少如果你的邏輯足夠複雜以至於你在解釋你的問題上有困難

0

我強烈建議savant而不是智者,

  • 你不必去學習,以創建模板的新模板「語言」,學者模板是用PHP編寫的
  • 如果你不」不想使用PHP,你可以用一個編譯器定義自己的模板「語言」
  • 它是由您自己的PHP易於擴展從presenta對象

邏輯分離這並不意味着你所有的業務邏輯都必須用php和你的表示邏輯來完成,分離是一個概念性的東西,你需要將準備數據的邏輯從顯示它的邏輯中分離出來。顯然,業務邏輯不必包含表示元素。

0

代替在模板系統之上實現模板系統(PHP本身),創建默認開銷,您可以選擇一個更強大的解決方案,如XSL Transformations,它也符合MVC princples(前提是您需要分離數據 - 檢索;另外,我個人將顯示XML的邏輯與不同的文件分開)。

想象一下你想在表格中顯示一個數組中的以下信息。

Array 
{ 
    [car] => green 
    [bike] => red 
} 

您可以輕鬆地創建一個腳本,在XML輸出這樣的信息:

echo "<VEHICLES>\n"; 
foreach(array_keys($aVehicles) as $sVehicle) 
    echo "\t<VEHICLE>".$sVehicle."</NAME><COLOR>".$aVehicles[$sVehicle]."</COLOR></VEHICLE>\n"; 
echo "</VEHICLES>\n"; 

在以下XML得到的:

<VEHICLES> 
    <VEHICLE> 
    <NAME>car</NAME> 
    <COLOR>green</COLOR> 
    </VEHICLE> 
    <VEHICLE> 
    <NAME>bike</NAME> 
    <COLOR>red</COLOR> 
    </VEHICLE> 
</VEHICLES> 

現在,這是所有優秀的,但不會以不錯的格式顯示。這是XSLT來與一些簡單的代碼,就可以將其轉化成一個表格:

<xsl:template match="VEHICLES"> 
    <TABLE> 
    <xsl:apply-templates select="VEHICLE"> 
    </TABLE> 
</xsl:template> 

<xsl:template match="VEHICLE"> 
    <TR> 
    <TD><xsl:value-of select="NAME"></TD> 
    <TD><xsl:value-of select="COLOR"></TD> 
    </TR> 
</xsl:template> 

的Et瞧,你有:

<TABLE> 
    <TR> 
    <TD>car</TD> 
    <TD>green</TD> 
    </TR> 
    <TR> 
    <TD>bike</TD> 
    <TD>red</TD> 
    </TR> 
</TABLE> 

現在對於這個簡單的例子,這是一個有點過度殺傷;但對於大型項目中的複雜結構,這是讓腳本邏輯遠離標記的絕對方法。

0

入住這question關於分離PHP和HTML,也有不同的方法來做到這一點,包括編寫自己的模板系統,模板系統,如Smarty的,PHP作爲它自己的模板系統,等等等等......

0

我想你在這裏有兩個選擇,要麼使用MVC框架,要麼使用懶惰的模板方式,這會給代碼帶來很大的開銷。很顯然,我與前者一樣,我認爲學習MVC是本書中最好的Web開發技巧之一。

2

但是,這樣做會讓我的php代碼看起來很可怕......它真的與代碼的格式和「形狀」混淆在一起。我應該如何解決這個問題?

將您的PHP和HTML視爲一個層次結構,並使用一個一致的縮進結構。因此,一個PHP封閉結構(如'if'或'for')引入了新的縮進級別,其內容始終是一組平衡的開始和結束標記。從本質上講,您使用PHP的「格式良好」來表達術語的XML含義,無論您是否實際使用XHTML。

例子:

<div class="prettybox"> 
    Hello <?php echo(htmlspecialchars($name)) ?>! 
    Your food: 
    <?php foreach($foods as $food) { ?> 
     <a href="/food.php?food=<?php echo(urlencode($food)) ?>"> 
      <?php echo(htmlspecialchars($food)) ?> 
     </a> 
    <?php } ?> 
    <?php if (count($foods)==0) { ?> 
     (no food today) 
    <?php } ?> 
</div> 

警惕周圍分離邏輯和標記的答案在這裏再次撫養它的頭宗教教條。雖然當然你想讓頁面輸出代碼保留商業邏輯,但這並不一定意味着使用單獨的文件,類,模板和框架所帶來的額外開銷對於你正在做的事情是非常必要的。對於一個簡單的應用程序,只需將動作/邏輯材料放在文件頂部和下面的頁面輸出即可。

(例如從上面的評論之一,做htmlspecialchars()是頁面輸出功能,你肯定是不要想把你的PHP的動作位放在所有的業務邏輯中。保持文本爲簡單的,未轉義的字符串,直到它離開你的應用程序邏輯爲止。如果一直輸入'echo(htmlspecialchars(...))'太冗長,你總是可以用一個簡短的名字如'h '也是這樣。)