【问题标题】:Catching certain errors with PHP eval()使用 PHP eval() 捕获某些错误
【发布时间】:2011-07-28 00:43:01
【问题描述】:

更新:我意识到 eval() 存在缺陷,但我“应该”将它用于这个特定问题。因此,任何解决该问题的方法都需要牢记这一点。

我刚刚开始在我的一个课程中使用 PHP,并且正在使用正则表达式(具体来说是 preg_match())和 eval() 实现一个非常有限的计算器。计算器的一个特点是,当它输入任何形式的错误时,会显示一条由我编写的简单错误消息,而不是默认的 PHP 错误。这适用于大多数错误输入(带有字母的字符串、连续的多个运算符等),但我无法捕捉到其他类型的错误。特别是输入:

0/0

诸如此类的东西

2--1

后一个表达式在技术上是正确的,但我不需要处理它(大概是为了让我们的代码更简单,因为这是一个让我们熟悉 PHP 的简单项目),而是可以将我的简单错误消息输出为回复。计算器不支持括号,所以像

这样的表达式
2-(-1)

无效。问题是我似乎无法弄清楚 eval() 在遇到这样的事情时会返回什么,如果它甚至返回的话。

eval() 总是返回吗?我已经阅读了 eval() 文档几次,但似乎仍然无法弄清楚我应该检查什么样的事情。我宁愿解释要检查的内容和原因,而不是盲目地检查返回值及其补码,直到我弄明白为止。以下是上述两个错误的屏幕截图(我没有足够的声誉将它们嵌入此处)。任何帮助将不胜感激!

Division by zero error

Multiple operator error

【问题讨论】:

    标签: php eval


    【解决方案1】:

    这似乎是一个苛刻的事情,但不要那样做!不要这样使用eval(),这很危险。除了它是一种更更安全的做事方式之外,您还可以通过编写一个简单的标记器将输入分解到您的计算器中,然后使用 Dijkstra 的 Shunting Yard algorithm 来了解更多信息 (a)将其转换为可以由堆栈机器评估的东西,并 (b) 识别令牌流中的意外令牌(例如您期望数字的运算符)。

    eval() 不能保证运行,因为您不仅在评估简单的表达式,还评估任意代码。

    如果您绝对必须使用eval(),请使用set_error_handler() 和@ 错误抑制运算符在错误向用户吐出之前拦截错误。您可以使用error_reporting() 函数来判断捕获的错误是否被@ 抑制。

    【讨论】:

    • 我同意这一点,但作业的重点只是熟悉 PHP,因为我们将在以后的作业中使用它(它是一个数据库系统类)。规范甚至告诉我们使用 eval()。
    • 再一次......我担心这是一个作业,而作业实际上建议使用 eval()。如果学校教出这样的坏习惯,那么像 SO 这样的在线开发社区肯定有责任尝试纠正这些坏习惯
    • 我敢肯定,如果该课程专注于 Web 开发之类的东西,它会得到解决,但在这种情况下,习惯使用 PHP 是理想的结果。但是我绝对很高兴在关于 eval() 的 SO 上阅读有关这个​​(以及似乎所有其他)问题的 cmets 之类的内容。并且要编辑我之前被告知使用 eval() 的声明,作业实际上说:“在实现您的计算器时,您可能会发现 PHP 函数 preg_match() 和 eval() 很有帮助。”
    • 有帮助,但不是必需的。不过,如果您确定必须使用 eval(),则可以使用 set_error_handler() 来拦截错误。我已经在我的回答中添加了一条注释。
    • 问题出在我对 === 和 !== 运算符的无知上。不过感谢您的帮助。
    猜你喜欢
    • 2011-03-14
    • 2013-11-14
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 2015-11-09
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    相关资源
    最近更新 更多