2012-03-20 139 views
1

想象一下你有一個存儲文章的mysql數據庫。在html中使用php代碼...在php

的HTML是存儲像這樣:

<h1>I'm just foo</h1> 
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p> 
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p> 

...

,並使用mysql_query中通過運行結果顯示。

但是,這裏的問題是:偶爾你可能想要使用預定義的函數,例如在html中插入一個映射。用戶如何在html中輸入?我不能很好地輸入:

<?php insertMap() ?> 

因爲這將呈現爲php標籤與php標籤內。

我見過不同的CMS以不同的方式處理它。例如使用{{{insertMap}}}來調用一個函數。但是,如何運行代碼,查找{{{}}}並將其作爲函數運行?谷歌和我有一種感覺eval()是解決方案的一部分(雖然存在安全風險?),但任何建議,指針等都是非常受歡迎的!

回答

2

基本上,您會在存儲的內容中進行查找和替換以匹配那些佔位符(其格式可由您自由決定),並將其替換爲您從中派生的表達式的評估結果。這是沒有必要的(或者一個好主意)使用eval,你可以很容易地推出自己的類似eval的代碼,只支持eval所做的安全子集。

假設您選擇{{{xxx}}}作爲佔位符模板。要匹配它,最簡單的方法是使用regular expressionspreg_match或同一系列中的其他功能;既然我們想要替換,我們希望動態生成替換,我們將使用preg_replace_callback

要更換的模式將爲'/{{{([a-zA-Z_]+)}}}/',它與花括號之間的一個或多個字母和下劃線的序列匹配。這裏的圓括號是正則表達式專用的語法,我使用它們,以便稍後可以很容易地引用(「模板」的名稱)內部的部分,而不會受到大括號的困擾。

回調將是產生給定的模式替換內容的功能:

function produce_replacement($match) { 
    // $match[1] means "the part of the template inside the braces"; 
    // read up on the documentation of preg_replace_callback for more. 
    $producerName = 'evaluate_'.strtolower($match[1]); 
    return function_exists($producerName) ? $producerName() : null; 
} 

此功能旨在利用模板名稱(例如,在{{{xxx}}}xxx),看看是否函數稱爲evaluate_xxx存在。如果是,則調用該函數並返回結果;如果不是,則返回null。無論如何,結果將會是原文中模板的替換。

重要提示:這是一個爲實施提供安全性的設計決策!我們已經取得了它,以便用戶可以使用任何的「模板」,他們希望裏面的文字,但如果代碼位於一個名爲evaluate_xxx或類似功能中的那些模板將被執行結果代碼。鑑於這些功能的存在或缺失是您控制的東西,用戶在其標記實際上可以做的事情上受到限制。

所以你現在可以有:

$text = "Hello there {{{name}}}!"; 
$pattern = '/{{{([a-zA-Z_]+)}}}/'; 

$text = preg_replace_callback($pattern, 'produce_replacement', $text); 
echo $text; 

function evaluate_name() { 
    return "Joe"; 
} 

​​

+0

哇,太棒了!感謝百萬,會盡快實現它:) – ThomasH 2012-03-20 09:26:39

+0

對不起,再次打擾你:)我已經或多或少地適應你的解決方案,以適應我的需要...將變量傳遞給我正在運行的功能,是一個挑戰。 .. 只有我不能繞到我的頭件事可能是非常簡單的:我有幾個電話,如{{{showMap}}},{{{showRating}}},{{{子項}}}在同一頁上。 如果我有三個不同的調用,只有第一個調用,但顯示三次。 任何意見指向我在正確的方向?謝謝 :) – ThomasH 2012-03-22 14:14:38

1

有很多模板引擎在做這件事,你可以不使用eval()。具有高級解析類。預定義您的功能列表等並使用它。或者只使用模板引擎。

+0

你實際上可以用五行代碼來做到這一點。無需模板引擎,解析類等。 – Jon 2012-03-20 09:25:01

+0

感謝您的反饋!將閱讀模板引擎。 – ThomasH 2012-03-20 09:27:31

+0

@Jon是的,但我寫的答案不僅僅是一個功能 – safarov 2012-03-20 10:10:14