![](/img/trans.png)
[英]Using a string variable as the condition of an if statement in php without using eval()
[英]Is it possible to use a string variable as the entire condition in an if block (without using eval() )?
作為背景,我正在編寫解析csv文件的PHP代碼,並對每個csv文件的每一行執行某些操作。 什么“東西”取決於行中的值。 使用“if”結構測試值很容易,但是,硬編碼條件並不是最佳的,原因有兩個:
有幾百個可能的條件需要測試。 那就是開始。 將來會增加更多條件。
每個csv行不需要針對每個條件進行測試; 只要行的條件評估為真,就不需要評估其他條件。
理想情況下,對於我的情況,“if”條件將存儲在postgres表中,逐個放入字符串變量,然后每個變量將由單個if結構(在某種循環內)測試,直到條件為止評估為真。
簡化示例:
$arrayOne[3] = "foo";
// in practice, the value of this variable would not be hard-coded;
// it would come from a postgres table
$conditionString="\$arrayOne[3] == \"VANILLA\"";
if($conditionString) {
// do something, then exit the loop this if statement would be
// inside of in actual practice
}
這個問題基本上是在問
有三個基本答案:
解決方案3通常是我正在尋找的,但第二部分似乎效率低下且不必要地復雜。 畢竟,為什么只需要存儲然后評估你需要的單個字符串就更容易了,為什么要從眾多字符串(順便提一下,這會使postgres中的存儲變得復雜)中構建php代碼?
有沒有辦法做到這一點?
非常感謝到目前為止的答復。 ComFreek,特別感謝您的詳細回復。 你建議的解決方案可能正是我所需要的,但坦率地說,如果是這種情況,我沒有經驗立即知道。 我肯定會花時間試圖理解你在說什么。 希望它能解決我的問題。
如果沒有,同時回答其他人提出的幾個問題:
1)if條件通常不簡單。 許多將包含多個復合AND和OR測試。 偽代碼中的樣本條件可能是:(field2 ==“BUY”AND(strpos(“REINVEST DIVIDEND”,field6)或strpos(“CASH MERGER,field6))AND field2!=”TTXY“AND field3> 0)。
2)CSV文件來自眾多金融機構。 它們包含大致相同的信息,但每個都有唯一的數據,並且所有數據都包含在不同位置的數據。 而且他們以不同的方式表達數據。 在某些情況下,付款用負數表示; 在其他人中,以正數表示。 有些人有單獨的存款和取款領域; 一些表示存款和取款,另一欄中有代碼。 等等。 代碼需要確定交易的性質(信用卡購買,支票,股票買賣,退休金,等等)然后,如果可以的話,分配正確的借方/貸方賬號(從圖表中帳戶)到該交易。 總而言之,有數百種可能的條件,可能成千上萬。 (如果有人想知道,代碼可以確定特定csv文件來自的機構,並將僅針對與該機構相關的條件測試該文件中的事務。)
3)代碼需要足夠靈活(以換句話說,無需編寫新代碼)允許將來添加新測試。 對我來說,能夠為postgres表添加一個新條件(這將是要檢查的代碼的另一個測試)是足夠的靈活性。
試圖回答Phil的問題和評論(我可能沒有正確理解):
1)我知道preg_match是什么,但還沒有真正探索它能做什么,所以它實際上可能是我的問題的答案。 我會檢查一下。
2)目前,代碼不對事務進行分組(也就是說來自單個csv文件的單行); 相反,它查看每一行,確定它是什么,然后在適當的postgres表中存儲一個額外的數據,然后移動到下一行。 交易存在某些“類型”(比如信用卡購買),但它們從未被分組以進行進一步處理。
3)每個交易應滿足唯一條件(盡管該條件可能很復雜)。
4)關於匹配整個字符串,除非我遺漏了某些東西(非常可能),否則就不那么簡單了。 例如,假設某個交易是股票購買。 代碼可以通過查看“action”字段包含單詞“Buy”並且“quantity”字段大於零來確定(僅這些條件中的一個或另一個可能不足以確定該交易是股票購買),但“自動收報機”字段可以是數千個事先未知的字符串中的任何一個 - “GOOG”,“MSFT”,“KO”或其他。
再次感謝所有回復到目前為止。
簡介 :為特定的比較類型構建可擴展的處理程序系統,並將相關數據存儲在數據庫中。
你需要 :
EqualityHandler
, StringLengthComparisionHandler
) 優點 :
該系統具有高度可擴展性。 如果你需要比較類型X或Y,只需編寫一個處理程序。 這實際上與瀏覽器或編輯器的插件系統相當。
您不在數據庫中存儲代碼。 存儲相同類型比較的代碼完全違反DRY原則( 不要重復自己 )。
單元測試。 當你有一個包含這些代碼的數據庫時,我無法想象單元測試是如何工作的。 他們真的很痛苦。
缺點 :
偽代碼 :
class EqualityHandler implements Handler
public function handle($handlerData, $data) {
// checks for equality and returns true or false
return true;
}
}
// TODO Act like Java: EqualityHandler.class (pass type of class)
$app->registerHandler('EqualityHandler');
// loop all rows
foreach ($row as $csvFields) {
foreach (retrieveConditions($row) as $condition) {
handleCondition($condition, $csvFields);
}
}
function handleCondition($condition, $csvFields) {
if ($app->getHandler($condition['type'])) {
return $app->instantiateHandler($condition['type'])->handle($condition, $csvFields);
}
else {
throw new HandlerNotFoundException('...');
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.