2009-08-18 70 views
0

我開始編寫我自己的小型框架,並且已經開始了它的模板部分。到目前爲止,我已經能夠做簡單的變量用下面的代碼替換:在模板中使用循環

public function view($page, $vars) 
{ 
    if(!file_exists('system/views/' . $page . '.php')) 
    { 
     trigger_error("No Template found", E_USER_ERROR); 
    } 

    $tempArray = file_get_contents('system/views/' . $page . '.php'); 

    foreach($vars as $key => $value) 
    { 
     $tempArray = str_replace('{' . $key . '}', $value, $tempArray); 
    } 

    print $tempArray; 
    unset($tempArray); 
} 

,工作正常,但我所尋找的是現在,如果我想環路從數據庫中讀出未知數量的記錄,我想思想的耦合器,但似乎沒有到目前爲止已經奏效

+0

有一個足夠的開源PHP模板語言,你爲什麼不看看其中之一? – Zed 2009-08-18 10:32:48

回答

1

首先,你應該重新考慮你的變量重寫。有幾種情況下,您的方法沒有按預期結束,當它們之間存在某些依賴關係時。另外,無論變量是否在循環中,一切都被替換。

如果你想要{while(condition)} code {/ while}之類的東西,你需要知道遞歸也是可能的,因此它不像在它上面匹配正則表達式那樣簡單。

一個簡單的方法是如下:

  • 查找令牌的開始(可變,while循環),並記住你找到它
  • 如果它是一個變量的位置和你在最外面的範圍(不在循環中),通過替換來處理它。調整你的指針,這樣你就不會再讀取替換,以避免替換你不想要的東西。
  • 如果它是一個循環
    • 提取括號之間的條件,並將其存儲somewher
    • additionaly,當前位置
    • 推令牌存儲到堆棧記住當前遞歸層次。
    • 當您遇到{/ while}令牌時,從堆棧中移除令牌。
    • 現在遞歸執行,將所有嵌套的循環標記推入堆棧並在它們結束時將其刪除。當你再次處於最外層時停止。
    • 評估循環的條件。只要它是真的,就從開始標記和結束標記之間的源文本創建新副本,並使用遞歸處理它們。
    • 連接中間結果並用此連接替換從{while}到{/ while}的所有內容。調整你的指針,以便你在循環後指出,繼續:)

希望這有助於。我知道這聽起來有點痛苦,但是如果你理解了這個概念,你應該可以做到這一點(儘管它不是超高效的,並且像smarty一樣編譯模板引擎將會提前完成,因爲它們僅僅解析模板文件一次並將其編譯爲PHP代碼)。

@Daff:你可以找到具有正則表達式的標記,但是使用一個正則表達式匹配整個循環結構由於遞歸(除非你的正則表達式具有遞歸擴展)不起作用。

+0

延遲迴復我知道,但我想我會讓你知道,這確實幫了很多,謝謝! – 2011-06-05 07:47:10

1

正如捷思銳已經表示,有很多模板語言PHP的,最流行的是Smarty的,我不知道這是否真的有意義除了學習目的以外,重新發明輪子。你想要做的循環實際上比替換元素複雜得多。我敢肯定,你可以通過很多正則表達式以某種方式做到這一點,但在某些時候,你最終將編寫自己的腳本語言(如Smarty的人),解析你的視圖文件,創建一個語法樹,評估它並將其編譯爲一個新的PHP文件。這非常複雜,因此我建議使用現有的模板引擎或使用PHP作爲模板語言本身(如果嚴格遵循MVC模式,即使有大量討論關於此模式也可能起作用)。

使用正則表達式,您可以解析{for ...} {/ for}之間的所有內容,以便訪問具有給定變量名稱的項目,其中{for和}定義變量發生後和之後} {/ for}你的html定義。這就像是一個foreach循環,你甚至不能相互嵌套。

{for item=$varname} 
    <p>{item.othervalue}</p> 
{/for} 
+0

我主要是在學習,肯定有辦法做到這一點,不涉及到這樣的極端情況? – 2009-08-18 10:56:20

+0

我添加了一個小例子,它的外觀如何。但是如果你想真正學習它,你可能想要走到一個極端......最簡單的就是使用PHP作爲你的模板語言,或者使用PHP創建你自己的模板引擎。 – Daff 2009-08-18 11:48:28

+0

謝謝你的例子,這似乎是我正在尋找的路線 – 2009-08-18 12:04:36