General
You cannot use eval() for this, as the evaled code will run in the current context, meaning that the evaled code can overwrite all vars in your context. Beside from security considerations this could / would break functionality. Check this imaginal example:
$mode = 'execute'
// here comes a common code example, it will overwrite `$mode`
eval('
$mode = 'test';
if(....) { ...
');
// here comes your code again, will fail
switch ( $mode) {
...
}
Error Tracking
You cannot track the errors this way. One method would be to use set_error_handler() to register a custom error handler which stores the errors to db. This would work, but what if the user uses the function in it's code? Check the following examples:
set_error_handler('my_handler');
function my_handler($errno, $errstr, $errfile, $errline) {
db_save($errstr, ...);
}
eval('
$a = 1 / 0; // will trigger a warning
echo $b; // variable not defined
'
);
This would work. But problems will arise if have an evaled code like this:
eval('
restore_error_handler();
$a = 1 / 0; // will trigger a warning
echo $b; // variable not defined
'
);
Solution
A common solution to make it possible that others can execute code on your servers is:
- store user code into temporary file
- disable critical functions like
fopen() ... in the php.ini
- execute the temporary php file by php-cli and display output (and errors) to the user
- if you separate stdin from stdout when calling the php-cli, you can parse the error messages and store them in a DB