PHP-PHP的eval()函数什么办法返回自定义的错误信息?

PHP-PHP的eval()函数什么办法返回自定义的错误信息?

夜无邪 发布于 2017-03-03 字数 372 浏览 1343 回复 3

我有一段PHP的代码需要用eval($code)来执行,有可能存在错误等,我现在的需求是当执行eval里的PHP代码出错里,返回自定义的错误信息,我不是要error_get_last()里的错误信息。

例如:
eval('$a=10; $b=0; $c=$a/$b;');
由于以上eval()里的代码是错的,所以在执行到$a/$b时就出错了,PHP脚本就退出了,但是我希望在出错脚本退出前输出$a的值,如果不出错就不输出,如何实现?

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

瑾兮 2017-10-21 3 楼

用buffer来解决

$code = eval('$a=10; $b=0; $c=$a/$b;');
ob_start();
$check = eval($code);
$output = ob_get_contents();
ob_end_clean();
if ($check === true) {
echo $output;
} else {
//捕获错误
$pattern = '/^s*Parse errors*:(.+) in (.+) on line (d+)s*$/m';
if(preg_match_all($pattern,$output,$matches)) {

}
}

php手册上提供了这个方法
Errors that occur in evaluated code are hard to catch. burninleo at gmx dot net posted some code below that will buffer the output of the evaluated code and search the output for errors. Another way you can do this would be using a custom error handler that's only in effect during the eval() of the code. A very (very) crude example:

$errors = array();
function error_hndl($errno, $errstr) {
global $errors;
$errors[] = array("errno"=>$errno, "errstr"=>$errstr);
}
function evale ($code) {
global $errors;
$errors = array();
$orig_hndl = set_error_handler("error_hndl");
eval($code);
restore_error_handler();
}

evale('print("foo" . $bar);'); // Undefined variable: bar
var_dump($errors);

//fooarray(1) {
// [0]=>
// array(2) {
// ["errno"]=>
// int(8)
// ["errstr"]=>
// string(23) "Undefined variable: bar"
// }
//}

This will however not catch syntax errors in the code you're trying to eval. This can cause your script to stop with a fatal error inside the eval(). You can catch syntax errors using the Parsekit PECL extension. The parsekit_compile_string() function will try to compile a piece of PHP code and will catch syntax errors if they occur. To extend the earlier piece of code:

 $errors = array();
function error_hndl($errno, $errstr) {
global $errors;
$errors[] = array("errno"=>$errno, "errstr"=>$errstr);
}
function evale ($code) {
global $errors;
$errors = array(); // Reset errors
$orig_hndl = set_error_handler("error_hndl");
if (parsekit_compile_string($code, &$errors, PARSEKIT_QUIET)) {
eval($code);
}
restore_error_handler();
if (count($errors) > 0) {
return(false);
} else {
return(true);
}
}

if (!evale('print("foo . $bar);')) { // syntax error, unexpected $end (no closing double quote)
var_dump($errors);
}

清晨说ぺ晚安 2017-08-15 2 楼

不知道我理解的正确不正确,用try{}catch{}实现

 $code = '$a=10; $b=0; $c=$a/$b;';
try {
$check = eval($code);
}
catch(Exception $e) {
//捕获错误
die('我的报错信息');
}

偏爱自由 2017-05-23 1 楼

我觉得用全局变量可能能基本上达到你的要求:例如以下代码,可以在定义$a之后,立即把这个$a赋值给全局变量my_error,然后在set_error_headler()定义的方法里输出,但是如果在$GLOBALS['my_error'] = $a这一句就出错了那就没办法了。不知道是不是你想要的。

 <?php
$GLOBALS['my_error'] = '';
set_error_handler('catchError');

function catchError(){
echo "出错信息:" . $GLOBALS['my_error'];
}

$code = eval('$a=10; $b=0; $GLOBALS["my_error"] = $a; $c=$a/$b;');
?>