Disclaimer; I'm fully aware of the pitfalls and "evils" of eval, including but not limited to: performance issues, security, portability etc.
The problem
Reading the PHP manual on eval...
eval() returns NULL unless return is called in the evaluated code, in which case the value passed to return is returned. If there is a parse error in the evaluated code, eval() returns FALSE and execution of the following code continues normally. It is not possible to catch a parse error in eval() using set_error_handler().
In short, no error capture except returning false which is very helpful, but I'm sur eI could do way better!
The reason
A part of the site's functionality I'm working on relies on executing expressions. I'd like not to pass through the path of sandbox or execution modules, so I've ended using eval. Before you shout "what if the client turned bad?!" know that the client is pretty much trusted; he wouldn't want to break his own site, and anyone getting access to this functionality pretty much owns the server, regardless of eval.
The client knows about expressions like in Excel, and it isn't a problem explaining the little differences, however, having some form of warning is pretty much standard functionality.
This is what I have so far:
define('CR',chr(13)); define('LF',chr(10)); function test($cond=''){ $cond=trim($cond); if($cond=='')return 'Success (condition was empty).'; $result=false; $cond='$result = '.str_replace(array(CR,LF),' ',$cond).';'; try { $success=eval($cond); if($success===false)return 'Error: could not run expression.'; return 'Success (condition return '.($result?'true':'false').').'; }catch(Exception $e){ return 'Error: exception '.get_class($e).', '.$e->getMessage().'.'; } }
Notes
So, what would you add to further aide the user? Is there any further parsing functions which might better pinpoint possible errors/issues?
Chris.
The eval() function evaluates a string as PHP code. The string must be valid PHP code and must end with semicolon. Note: A return statement will terminate the evaluation of the string immediately. Tip: This function can be useful for storing PHP code in a database.
Since PHP 7 eval() will generate a ParseError
exception for syntax errors:
try { $result = eval($code); } catch (ParseError $e) { // Report error somehow }
In PHP 5 eval() will generate a parse error, which is special-cased to not abort execution (as parse errors would usually do). However, it also cannot be caught through an error handler. A possibility is to catch the printed error message, assuming that display_errors=1
:
ob_start(); $result = eval($code); if ('' !== $error = ob_get_clean()) { // Report error somehow }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With