为了账号安全,请及时绑定邮箱和手机立即绑定

什么时候php中的EVE是邪恶的?

什么时候php中的EVE是邪恶的?

PHP
慕丝7291255 2019-06-01 15:50:23
什么时候php中的EVE是邪恶的?在我开发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')";// possibility one$type_1 = preg_replace('#^enum\s*\(\s*\'|\'\s*\)\s*$#', '', $type);$result = preg_split('#\'\s*,\s*\'#', $type_1);// possibility twoeval('$result = '.preg_replace('#^enum#','array', $type).';');
查看完整描述

4 回答

?
慕码人8056858

TA贡献1803条经验 获得超6个赞

我会谨慎地称val()为纯粹的邪恶。动态评估是一个强大的工具,有时也可以成为生命的拯救者。有了val(),就可以解决PHP的缺点(见下文)。

val()的主要问题是:

  • 潜在的不安全输入。

    传递不受信任的参数是失败的一种方法。确保参数(或参数的一部分)完全可信通常不是一项简单的任务。
  • 诡计。

    使用val()使代码更聪明,因此更难以理解。引用布赖恩·克尼汉的话

    调试的难度是编写代码的第一步的两倍。因此,如果您尽可能聪明地编写代码,那么根据定义,您就没有足够的智能来调试它。"

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

  • 没有经验的开发人员谁使用它没有足够的考虑。

根据经验,我倾向于这样做:

  1. 有时val()是唯一/正确的解决方案。
  2. 在大多数情况下,人们应该尝试其他的东西。
  3. 如果不确定,去2。
  4. 否则,

    非常小心。


查看完整回答
反对 回复 2019-06-01
?
智慧大石

TA贡献1946条经验 获得超3个赞

当用户输入被包含在计算的字符串中时,Eval是邪恶的。当您不使用来自用户的内容时,您应该是安全的。

尽管如此,在使用val之前至少要考虑两次,它看起来非常简单,但是使用错误处理(请参阅VBAssassins的注释)、可调试性等等。在心里,这已经不是那么简单了。

因此,作为一个经验法则:忘记它。当伊娃是答案时,你很可能问错了问题!-)


查看完整回答
反对 回复 2019-06-01
?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

Eval()在任何时候都是同样邪恶的。

“什么时候才不邪恶?”在我看来,这是一个错误的问题,因为它似乎意味着在某些情况下,使用val()的缺点神奇地消失了。

使用val()通常是个坏主意,因为它降低了代码的可读性,降低了您在运行时之前预测代码路径(以及可能的安全含义)的能力,从而降低了调试代码的能力。使用val()还可以防止操作码缓存(如集成到PHP 5.5和更高版本的Zend Opcache)或JIT编译器(如HHVM中的JIT编译器)对评估的代码及其周围的代码进行优化。

此外,没有任何情况下绝对有必要使用val()-PHP是一种功能齐全的编程语言,没有它。

在某些情况下,您是否真的将这些看作是邪恶的,或者您是否可以亲自证明使用val()是由您来决定的。对一些人来说,罪恶太大了,根本无法证明它是正当的,而对另一些人来说,val()是一条便捷的捷径。

但是,如果您认为val()是邪恶的,那么它在任何时候都是邪恶的。它并不会神奇地失去它的邪恶取决于背景。


查看完整回答
反对 回复 2019-06-01
?
暮色呼如

TA贡献1853条经验 获得超9个赞

在这种情况下,只要用户永远不可能在表中创建任意列,val就可能是足够安全的。

不过,它已经不太优雅了。这基本上是一个文本解析问题,滥用PHP的解析器似乎有点麻烦。如果您想滥用语言特性,为什么不滥用JSON解析器呢?至少对于JSON解析器,根本不可能注入代码。

$json = str_replace(array(
    'enum', '(', ')', "'"), array)
    '',     '[', ']', "'"), $type);$result = json_decode($json);

正则表达式可能是最明显的方式。可以使用单个正则表达式从此字符串提取所有值:

$extract_regex = '/
    (?<=,|enum\()   # Match strings that follow either a comma, or the string "enum("...
    \'      # ...then the opening quote mark...
    (.*?)       # ...and capture anything...
    \'      # ...up to the closing quote mark...
    /x';preg_match_all($extract_regex, $type, $matches);$result = $matches[1];


查看完整回答
反对 回复 2019-06-01
  • 4 回答
  • 0 关注
  • 485 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信