PHP eval和捕获错误(尽可能多) [英] PHP eval and capturing errors (as much as possible)

查看:551
本文介绍了PHP eval和捕获错误(尽可能多)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

<强> 声明;我完全意识到eval的缺陷和邪恶,包括但不限于:性能问题,安全性,可移植性等。

Disclaimer; I'm fully aware of the pitfalls and "evils" of eval, including but not limited to: performance issues, security, portability etc.

问题

阅读关于eval的PHP手册

Reading the PHP manual on eval...


eval()返回NULL,除非在评估代码中调用
,其中
返回的值传递给
。如果
中有一个解析错误的评估代码,eval()返回
FALSE,并执行以下
代码继续正常。使用set_error_handler()可以在
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().

短,没有错误捕获,除了返回false这是非常有帮助的,但我可以做得更好!

In short, no error capture except returning false which is very helpful, but I'm sur eI could do way better!

原因

我正在使用的一部分网站的功能依赖于执行表达式。我不想通过沙箱或执行模块的路径,所以我已经结束了使用eval。在你喊出来之前,如果客户变坏了怎么办?知道客户几乎相信;他不想破坏自己的网站,任何获得此功能的人都可以很容易地拥有服务器,而不管eval。

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.

客户端知道如Excel,这不是一个解释一点点差异的问题,但是,有一些形式的警告是几乎标准的功能。

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.

这是我到目前为止:

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().'.';
    }
}

备注


  • 该函数在任何情况下返回消息字符串

  • 代码表达式应为单行PHP,没有PHP标签,没有结尾的分号

  • 新行转换为空格

  • 添加一个变量来包含结果(表达式应该返回为了不与eval的返回冲突,使用一个临时变量。)

  • The function returns a message string in any event
  • The code expression should be a single-line piece of PHP, without PHP tags and without an ending semicolon
  • New lines are converted to spaces
  • A variable is added to contain the result (expression should return either true or false, and in order not to conflict with eval's return, a temp variable is used.)

那么,你会添加进一步帮助用户?有没有进一步的解析功能可以更好地找出可能的错误/问题?

So, what would you add to further aide the user? Is there any further parsing functions which might better pinpoint possible errors/issues?

Chris。

推荐答案

我已经找到了一个很好的选择/解答我的问题。

I've found a good alternative/answer to my question.

首先,让我开始说,nikic的建议工作,当我设置使用error_reporting(E_ALL);通知显示在PHP输出中,并且通过OB,可以捕获它们。

First of, let me start by saying that nikic's suggestion works when I set error_reporting(E_ALL); notices are shown in PHP output, and thanks to OB, they can be captured.

接下来,我发现这个非常有用的代码:

Next, I've found this very useful code:

/**
 * Check the syntax of some PHP code.
 * @param string $code PHP code to check.
 * @return boolean|array If false, then check was successful, otherwise an array(message,line) of errors is returned.
 */
function php_syntax_error($code){
    if(!defined("CR"))
        define("CR","\r");
    if(!defined("LF"))
        define("LF","\n") ;
    if(!defined("CRLF"))
        define("CRLF","\r\n") ;
    $braces=0;
    $inString=0;
    foreach (token_get_all('<?php ' . $code) as $token) {
        if (is_array($token)) {
            switch ($token[0]) {
                case T_CURLY_OPEN:
                case T_DOLLAR_OPEN_CURLY_BRACES:
                case T_START_HEREDOC: ++$inString; break;
                case T_END_HEREDOC:   --$inString; break;
            }
        } else if ($inString & 1) {
            switch ($token) {
                case '`': case '\'':
                case '"': --$inString; break;
            }
        } else {
            switch ($token) {
                case '`': case '\'':
                case '"': ++$inString; break;
                case '{': ++$braces; break;
                case '}':
                    if ($inString) {
                        --$inString;
                    } else {
                        --$braces;
                        if ($braces < 0) break 2;
                    }
                    break;
            }
        }
    }
    $inString = @ini_set('log_errors', false);
    $token = @ini_set('display_errors', true);
    ob_start();
    $code = substr($code, strlen('<?php '));
    $braces || $code = "if(0){{$code}\n}";
    if (eval($code) === false) {
        if ($braces) {
            $braces = PHP_INT_MAX;
        } else {
            false !== strpos($code,CR) && $code = strtr(str_replace(CRLF,LF,$code),CR,LF);
            $braces = substr_count($code,LF);
        }
        $code = ob_get_clean();
        $code = strip_tags($code);
        if (preg_match("'syntax error, (.+) in .+ on line (\d+)$'s", $code, $code)) {
            $code[2] = (int) $code[2];
            $code = $code[2] <= $braces
                ? array($code[1], $code[2])
                : array('unexpected $end' . substr($code[1], 14), $braces);
        } else $code = array('syntax error', 0);
    } else {
        ob_end_clean();
        $code = false;
    }
    @ini_set('display_errors', $token);
    @ini_set('log_errors', $inString);
    return $code;
}

似乎很容易做到我所需要的(yay)!

Seems it easily does exactly what I need (yay)!

这篇关于PHP eval和捕获错误(尽可能多)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆