在 PHP 中,何时使用 eval 函数是不好的?

90

在我多年的PHP开发经验中,我一直听说使用eval()是邪恶的。

考虑下面的代码,使用第二种(更优雅)的选项不是很合理吗?如果不是,请说明原因。

// $type is the result of an SQL statement, e.g.
// SHOW COLUMNS FROM a_table LIKE 'a_column';
// hence you can be pretty sure about the consistency
// of your string.

$type = "enum('a','b','c')";

// option one
$type_1 = preg_replace('#^enum\s*\(\s*\'|\'\s*\)\s*$#', '', $type);
$result = preg_split('#\'\s*,\s*\'#', $type_1);

// option two
eval('$result = '.preg_replace('#^enum#','array', $type).';');

3
"eval永远是有害的,在编写代码时总有更好的方法,特别是自从PHP引入匿名函数以来。在这种情况下,我会使用 $result = array(); preg_replace_callback('#^enum\s*\(\s*\'|\'\s*\)\s*$#', function($m) use($result) { $result[] = $m[1]; }, $type);" - Geoffrey
说实话,我认为 PHP 的主要问题不在于语言本身,而在于使用它的人。对于这个问题,三个正确的答案(thomasrutter、braincracking 和我的)都被投了反对票,却没有人提出任何反对意见。另一方面,有一个回答声称“有时 eval() 是唯一/正确的解决方案”,却没有举例或解释,却因此得到了最高票数... - Francois Bourgeois
21个回答

-1

评估没问题,

现在是时候永远结束这场辩论了。(我知道这是一个老话题,但是是的,今天仍然发生着,并且人们几乎宗教般地否认一件有益的事情,真是令人惊讶。)

所以,请考虑以下内容:

  • 放弃使用include/require?
    当你使用任何形式的包含时,实际上就是对一个文件进行eval(...)。虽然有一些区别,但如果你如此鲁莽地将未经过滤的用户输入写入php文件并进行包含,那么你会遇到麻烦。现在告诉我你想停止使用include和require。

  • 你怎么不知道呢?
    如果你不确定一个字符串是否可能包含恶意代码,请离开电脑。说真的,很多事情都可能伤害到你,如果安全不是你24/7关注的重点,那么你的问题与eval无关。更好地验证和清理数据。考虑潜在的攻击。别误伤善良的人。

  • 自己解析
    有些情况下,你可能需要评估一些东西,比如逻辑或数值表达式,解决所有括号和优先级,你可以使用eval来完成工作,但出于恐惧,你选择编写自己的解析器。这时候你把孩子扔掉了,却还留着所有的洗澡水。相比从头开始构建一个数学解析器,清理进入eval的任何内容要容易得多 - 一个像5*(12/3+7*(45+12)-65*1)这样的计算可以在你的eval之前通过简单的正则表达式安全检查来处理;现在让我们看看一个恶意黑客如何只用数字和括号就能攻破五角大楼。另一方面,你自己的解析器可能会以很多方式出乎你的意料,我并不是说你不够好,但即使你有经验并且是波兰人,这也相当复杂。

所以,对于使用eval要小心一点怎么样?而不是在别人用错的时候就说它是错误的。
case 'TLDR':
称呼语句和技术为“有害”的原因正是机器有一天会崛起的根本原因,他们将高举着写着“这不是我们的错”的旗帜行进。我站在他们这一边。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接