什么时候在php中eval evil?

2022-08-30 08:01:14

在我用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).';');

答案 1

我会谨慎地称eval()为纯粹的邪恶。动态评估是一个强大的工具,有时可以挽救生命。使用eval()可以解决PHP的缺点(见下文)。

eval() 的主要问题是:

  • 潜在的不安全输入。传递不受信任的参数是一种失败的方法。确保参数(或其一部分)完全受信任通常不是一件容易的事。
  • 棘手。使用eval()使代码变得聪明,因此更难理解。引用 Brian Kernighan 的话:“调试的难度是编写代码的两倍。因此,如果你尽可能聪明地编写代码,根据定义,你不够聪明,无法调试它。"

实际使用eval()的主要问题只有一个:

  • 没有经验的开发人员,他们使用它时没有经过足够的考虑。

根据经验,我倾向于遵循以下几点:

  1. 有时 eval() 是唯一/正确的解决方案。
  2. 在大多数情况下,应该尝试其他东西。
  3. 如果不确定,请转到 2。
  4. 否则,要非常非常小心。

答案 2

当用户输入包含在计算的字符串中的可能性只有丝毫的可能性时,eval 是邪恶的。当您在没有来自用户的内容的情况下进行评估时,您应该是安全的。

然而,在使用eval之前,您应该至少三思而后行,它看起来非常简单,但是考虑到错误处理(请参阅VBAssassins注释),可调试性等,它不再那么简单了。

因此,根据经验法则:忘记它。当eval是答案时,你很可能问错了问题!;-)


推荐