2011-08-29 55 views
7

在我們當前的應用程序,我有一個包含類似的報告:如何在數據庫中存儲PHP條件屬性以備後用?

if($foo == 3 || $bar > 3) { 
    $e = someFunction(); 
}; 

但對於不同的客戶端相同的表達可能是:

if($foo == 3 || $bar == 5 && $foobar != 9) { 
    $e = someFunction(); 
}; 

是否有存儲一個直接的方法兩個不同的表達式,只是

$foo == 3 || $bar > 3 OR $foo == 3 || $bar == 5 

位數據庫(MySQL),所以我不必硬編碼所有這些規則由客戶端或維護相同報告的客戶端版本。我試圖找出是否可以設置變量來替換條件。例如:

$conditions = $row_rsConditions['condition_row'] //Get $foo == 3 || $bar > 3 from the DB and store it as $conditions 
if($conditions) { 
    $e = someFunction(); 
}; 

可能有100多個不同的客戶端,每個客戶端可能會有不同的表達式集。 我只是不確定正確/最好的方式來做到這一點。

UPDATE

我想我明白使用PHP的eval()函數的問題。但由於我傾向於使用數據庫來存儲條件(尚不確定使用eval())的可能組合的數量,因此尚未確定使用eval())

如果沒有面向用戶的界面,它會產生任何區別(更安全)嗎?寫入條件字段/表?這可能是我們單獨管理的事情。

+4

如何保存代碼數據庫,後來加載和執行使用'eval' ?當有人注入數據庫並讓你評估他的代碼時,你可能會遇到安全問題。 – Nobody

+0

那麼問題是,在哪些情況下,那些條件內的操作員可以改變? – Deele

+5

我認爲這是很糟糕的設計在數據庫存儲的邏輯,數據庫應僅用於數據 – Fivell

回答

3

我會非常小心地將邏輯存儲在數據庫中。

  1. 你的代碼不再在一個地方。
  2. 數據庫中的邏輯不太可能在源代碼控制下如果您更改代碼並中斷所有客戶端特定邏輯,則必須返回到數據庫併爲每個客戶端進行編輯。
  3. 其他人可以訪問數據庫並可以將代碼更改爲惡意代碼。

這可能不是最好的解決辦法 但我建議建立一個抽象基類,然後從該繼承,具體到每一個客戶端類。

被定製的任何功能都可以被添加爲基類的方法,以及重寫客戶端具體實施。

使用switch語句來實例化基於客戶端ID或名稱(東西不會改變),您已經在數據庫中存儲類。

switch ($client_name) { 

case "abc ltd": 
    $customlogic = new CustomLogicAbc(); 
    break; 

case "zyx ltd": 
    $customlogic = new CustomLogicXyz(); 
    break; 

default: 
    $customlogic = new CustomLogicDefault(); 
    break; 

} 

if ($customlogic->doSomething($parm1, $parm2)) { 
    // custom logic has been applied 
} 
+0

我認爲問題相對簡單,這意味着他只會檢查這兩個值。但他有很多不同的條件,所有條件都必須進行編碼。相反,參數化只需要一個實現並根據需要獲取條件。 – Nobody

+0

那麼如果有100多個客戶,這個選項仍然可行?我會同意你的#1和#2分。 #3在我們身上保持正常,#4 - 如果他們可以改變那麼他們可以做更多的傷害,對吧? – Jason

+0

它確實取決於你有多少定製邏輯以及它有多複雜。如果你的示例中只顯示了1條語句,那麼最好將$ foo和$ bar參數存儲在數據庫中,而不是每個客戶端記錄,而不是實際的邏輯本身。如果你有很多定製的報表,他們是複雜的,那麼我會做我在上面所做的,因爲機會是邏輯只會讓你去更復雜,你會加入更多個性化的東西,以及 – bumperbox

2

要闡述我的意見:

你最後的代碼幾乎是我的意思:

$conditions = $row_rsConditions['condition_row']; //Get "$foo == 3 || $bar > 3" 
if(eval("return (" . $conditions . ");")) { 
    $e = someFunction(); 
} 

但是我會再次提醒你記住這樣做的風險。 當您使用數據庫中的代碼時,很可能是內部錯誤。 至少應該對數據進行一些安全檢查以避免誤用。

另一個稍微複雜但不容易被濫用的選擇是編碼條件。因爲它似乎是你只比較兩個變量有值的每個可以爲您節省每一個變量是這樣的:

0 != 
1 == 
2 >= 
3 <= 
4 > 
5 < 

要保存的關係,另外保存的值,該應進行比較。這樣就不會直接執行保存在數據庫中的代碼。

+0

非常不安全! – Gustav

+0

@Gustav - 它是不安全的,因爲我會開闢一個地方允許的代碼注入或者是有什麼比這更? – Jason

+0

@Jason PHP注入部分是最糟糕的。 – Gustav

0

沒有人可以告訴你如何因爲沒有人知道的功能需求和應用程序的特定邏輯來解決它......但是,如果執行的時間對你很重要,你可以ofcourse嘗試使用表達式evaluationg從數據庫,但要小心,並使用從數據庫中所有數據的sanitazing ...有一個例子how to make php expressions and execute from database? - 你只需要添加更多的邏輯,因爲你可以有多重條件

相關問題