2011-04-01 62 views
0

更新:我意识到eval()存在缺陷,但我“被认为”将其用于此特定问题。所以任何解决这个问题的方法都需要牢记这一点。使用PHP eval捕获某些错误()

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

0/0 

之类的东西

2--1 

后者表达在技术上是良好的,但我不需要处理它(大概是为了保持我们的代码,因为这是更简单一个简单的项目,让我们熟悉PHP),并可以输出我的简单错误消息作为回应。该计算器不支持括号,因此表达式如下:

2-(-1) 

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

eval()总是返回吗?我已经阅读了几次eval()文档,但似乎无法弄清楚我应该检查哪些东西。我宁愿解释什么是检查和为什么,而不是盲目地检查返回值及其补码,直到我弄明白为止。以下是上述两个错误的截图(我没有足够的声望将它们嵌入到这里)。任何帮助,将不胜感激!

Division by zero error

Multiple operator error

回答

2

这似乎是一个恶劣的事情要说,但不这样做!不要这样使用eval(),这很危险。除了它是一个许多更安全的方式来做事情,你会通过写一个简单的记号器来打破输入到你的计算器了解更多,然后使用Dijkstra的Shunting Yard algorithm(a)把它变成可以(b)识别令牌流中的意外令牌(例如期望数字的运算符)。

eval()不能保证运行,因为你不只是评估简单表达式,而是评估任意代码。

如果您绝对必须使用eval(),请使用set_error_handler()@错误抑制运算符在错误发生之前拦截错误。您可以使用error_reporting()函数来判断捕获的错误是否使用@进行了抑制。

+0

我同意这一点,但分配的重点仅仅是熟悉PHP,因为我们将在将来的任务(它是一个数据库系统类)上使用它。规范甚至告诉我们要使用eval()。 – 2011-04-01 22:55:41

+0

又是......我的担心是这是一项任务,而任务实际上建议使用eval()。如果学校教这样的坏习惯,那么肯定的责任就是像SO这样的在线开发社区尝试纠正这些不良习惯 – 2011-04-01 22:59:34

+0

我相信,如果课程着重于网络开发,它会解决这个问题,但在这习惯使用PHP的情况是期望的结果。但是我很高兴看到关于eval()这个(和看似其他所有)关于SO的问题的评论。为了编辑我以前的声明,我们被告知要使用eval(),该任务实际上是这样说的:“在实现计算器时,您可能会发现PHP函数preg_match()和eval()有帮助。” – 2011-04-01 23:04:18