【问题标题】:Eval(), what's the point?eval(),有什么意义?
【发布时间】:2011-01-25 18:25:44
【问题描述】:

关于 eval() 作为函数的官方文档说:

除其他外,这对于将代码存储在数据库文本字段中以供以后执行很有用。

我对此感到非常困惑。 PHP 文档是否建议将 PHP 行存储到数据库中?什么?这不是很不安全吗?

如果我知道数据库中有一个作为 PHP 执行的字符串怎么办?这不是非常危险吗?我只需要一个 Sql 注入来对那个站点做任何我想做的事情,我想做的任何事情。我可以删除整个数据库,我可以从脚本中获取所有内容,我可以做所有事情。

这怎么会有这么大的帮助?

您能否提供一些示例,说明eval() 的用途? 另外,我可能遗漏了一些东西,为什么我看到了一些类似的代码:

eval("if (is_int($int)) { return false }");

而不仅仅是

if (is_int($int)) { return false }

但是,正如我所说,我可能遗漏了一些东西:什么?

【问题讨论】:

  • 好问题。我不知道eval() 的用途不能用其他东西做得更好。但我在听……
  • 这个点好像被打到地下了,eval() 不好,我们明白了。
  • 写了一个小脚本解析器后,我可以证明你有 eval 的有效用途。但除了边缘情况,eval() 只是 include() 的另一个名称,它不依赖于文件。
  • eval 用于补充变量变量直接sql字符串操作。现在不想制造任何不公平或不平衡的东西! ;-)
  • 总体来说,有它还好。只是不要使用它。 :|

标签: php eval


【解决方案1】:

eval() 功能太棒了!人们一直使用它来注入代码并始终获得对服务器的出色访问权限。您会经常看到eval() 的使用,以及在损坏的 WordPress 安装中也会执行的正则表达式函数。

您需要 eval 的原因很少。例如,如果我正在创建一个 PHP 测试站点,人们可以在其中在页面上输入一些代码然后运行它。当然,由于您列出的原因,它需要首先进行消毒。

【讨论】:

  • 正确使用 eval() 非常有用。您可以在许多 drupal 模块中看到一些示例(想到 cck)
  • @AntonioCS,毫无疑问,但我无法告诉你我必须修复多少被黑的 Drupal(以及其他)安装。我不否认它可能有用,但我确实认为它会带来麻烦。没有人的代码是完美的。甚至 Jon Skeet 的也不行。 (或者是。:-D)
【解决方案2】:

假设您有一个允许您键入 PHP 代码的 CMS。我可以看到使用 eval 函数来评估 PHP sn-p。出于同样的原因,Javascript 也有 eval。

抛开所有原因,eval 非常不安全。我同意它永远不应该被使用。

【讨论】:

  • 有一些 CMS' 使用这种技术,其中一些被认为是“流行的”。 “视图布局”、菜单等作为 php 代码存储在数据库中。通常需要能够更改这些代码(布局、菜单插件等)。我想这是使主题文件可由网络服务器写入的替代方法,例如,Wordpress 就是这样做的。但是使用 eval 的代码味道很糟糕。
【解决方案3】:

是的,这可能非常危险。我见过它使用的一个地方是一个允许非常复杂的搜索屏幕配置的系统,并允许用户保存搜索配置。搜索的详细信息被保存为作为 eval 执行的实际代码。 inputs 被单独存储并被检查(在某种程度上,我不知道细节)以防止 SQL 注入。这是我唯一一次看到这样做,而且可能没有必要(尽管我从未见过足够多的系统来确定)。

eval() 在您不知道在运行时之前需要执行哪些代码时可能很有用(就像我上面给出的示例),但是对于大多数开发人员来说,这些情况并不是每天都会发生的事情。如果您确实遇到了需要eval()的情况,请尝试确保从不直接从用户。如果你能找到一种方法来限制(在某种程度上)将传递给它的代码,那就更好了,但这取决于手头的问题。

【讨论】:

    【解决方案4】:

    能否请您提供一些有关此 eval() 如何有用的示例?

    它被模板引擎使用,例如。他们将模板解析和编译为 PHP 代码,并且可以将代码存储到任何位置,或者直接使用eval() 执行它。

    除此之外,这是一个危险的功能。

    【讨论】:

    • 你能举一个模板引擎的例子吗?
    • 我会说大部分; SmartyTwig 做。
    • 这就是我讨厌模板引擎的原因。
    • @Charlie Pigarelli:这不是讨厌他们的理由。如果缓存被禁用,他们只使用eval 作为最后的手段。此外:如果代码正确地检查了恶意代码,那么使用 eval 确实没有问题;)
    • 抱歉,我应该指出这一点:这也是为什么我讨厌像 Smarty 这样的模板引擎。我永远不会使用它们,即使 eval() 不是脚本的一部分。因为他们根本没有意义。您可以使用 PHP 本身(也分离逻辑和视图)来完成您对模板引擎所做的一切,更快且无需缓存。
    【解决方案5】:

    这确实是不安全的,无论如何你都必须清理你的代码。

    但它并不打算评估用户引入的表达式或任何其他方式(例如来自 DB)。

    当语言不提供元编程时,我发现它很有用。因此,例如,您需要用 50 个字段填充一个 bean,这些字段被称为相同但方法名称略有不同,例如数字(想象它有 field1()、field2()、field3() ......等) , 那么你可以使用 for 中的 eval: 将方法名构造为字符串然后调用它。

    通过这种方式,您可以在 5 中转换 100 行重复的代码,如果您想添加有关其工作原理的文档,还可以再多几行。哈哈。这并不是不安全的,因为这里没有其他人接触您的代码。

    【讨论】:

    • +1 尽管支持 OP 的主观模因问题和模糊且无法实现的“清理你的代码”短语。当闭包不足时,元编程确实是一种有效的用途。
    • 可以改写为:$object -> $method (根本不需要eval)
    【解决方案6】:

    你可以有类似的东西

    $text = 'This is some random number: $number. Hello world!';
    ...
    $number = 15;
    ...
    eval ("\$replacedText = \"$text\";");
    

    在 eval 中,$text 将被替换为“这是一些随机数:$number。Hello world!”,并且 eval 确保 $number 也被替换为 15

    【讨论】:

    • str_replace 怎么样? $text = str_replace('$number', '15', $text); 做同样的事情。
    • @user576875:还是双引号?
    • 我想我错过了一些东西。 $number 永远不会用单个 (') 替换为字符串。是吗?
    • @Jonah,在意大利,现在是晚上,我很累,可能比平时更愚蠢,但我认为创建问题并使用 eval() 解决它没有任何意义。跨度>
    • @Charlie:我同意。我没有为答案辩护,只是解释它(不管它多么荒谬)。这 ”???”被指向答案,而不是你;)
    猜你喜欢
    • 2016-03-29
    • 2014-03-08
    • 1970-01-01
    • 2011-09-26
    • 2010-11-29
    • 2010-10-15
    • 2011-02-05
    • 2012-02-28
    • 2018-01-13
    相关资源
    最近更新 更多