2016-08-20 106 views
1

對於我正在處理的複雜項目,我希望管理員可以使用布爾表達式將事件附加到事件。評估PHP表達式邏輯 - 但沒有eval()?

實施例:

if (1 > 2 || (1 == 1 && 3 > 2)) [...] 

上面將返回TRUE。

eval()看起來像一個簡單的解決方案,但我很清楚它提出的安全風險。 PHP是否提供了一種評估上述表達式的方式,而無需實際評估其他任意PHP代碼?選項可以是隻評估數學表達式的東西,或者是接受功能白名單的消毒劑。

感謝您的幫助!

+3

否.............. –

+1

我不會使用regexp來嘗試清理數據以進行計算;我會考慮編寫一個計算器,也許基於[this](http://stackoverflow.com/questions/12692727/how-to-make-a-calculator-in-php) –

+0

Mark的建議非常好。否則,你可以構建一個遞歸解析器([這裏是一個很好的例子])(http://stackoverflow.com/questions/35426793/parsing-a-string-with-recursive-parentheses)) –

回答

1

最好的事情是爲你的建議「消毒液」,使用token_get_all

下面

(不完全)段,這樣以來EVAL結構是很危險的,你應該嘗試注入你可能會得到的想法

function evalExpression ($expression) 
{ 
    $code = "return $expression;"; 
    $token = token_get_all($code,TOKEN_PARSE); 

    # return 
    unset($token[1]); 

    foreach ($token as $key=>$value) { 

     if(is_array($value)) { 

      # white list token 
      $allow = [T_WHITESPACE,T_LNUMBER,/* add more token*/]; 

      # remove white list token 
      if(in_array($value[0],$allow,true)) { 
       unset($token[$key]); 
      } 

     } else { 

      # white list string 
      $allow = [';','>'/* add more element*/]; 

      # remove white list string 
      if(in_array($value,$allow,true)) { 
       unset($token[$key]); 
      } 

     } 

    } 

    # if token contain only white listed, $token should empty 
    if(!$token) { 
     return eval($code); 
    } else { 
     throw new \InvalidArgumentException('err'); 
    } 

}; 

# return bool 
var_dump(evalExpression('2 > 1')); 

# should error 
var_dump(evalExpression('function(){}')); 

/使用惡意代碼進行測試,然後投入生產