【问题标题】:Using PHP eval to run code causes Fatal error: Cannot redeclare function使用 PHP eval 运行代码导致致命错误:无法重新声明函数
【发布时间】:2016-08-24 20:39:08
【问题描述】:

我有一个 PHP 脚本,它从数据库中选择许多 PHP 代码 sn-ps 之一并使用 eval 执行它。在某些情况下,如果两个代码 sn-ps 尝试声明具有相同名称的函数,我会收到致命错误“无法重新声明函数”。在代码 sn-ps 中编辑函数名称不是一种选择。有没有办法创建一个范围或者让函数相互覆盖?还是有其他更好的想法?

谢谢。

编辑:循环这段代码。

ob_start();
try {
    $result = eval($source_code);
} catch(Exception $e) {
    echo "error";
}
$error = ob_get_clean();

【问题讨论】:

  • 我们能看看你到底想做什么吗?
  • @DevDonkey 我可以完美地看到代码!你不是通灵者还是什么?接受它:-)
  • 如果您发布一些我们可能会提供帮助的代码,否则如果没有重命名函数或将其移动到类中,您可能会很不走运。你也可以使用function_exists
  • 放弃评估!
  • @DevDonkey 好了。

标签: php eval


【解决方案1】:

真的,你有三个选择。

function_exists()

// this will check for the function's existence before trying to declare it
if(!function_exists('cool_func')){
    function cool_func(){
        echo 'hi';
    }
}

// business as usual
cool_func();

给变量赋值

// this will automatically overwrite any uses of $cool_func within the current scope
$cool_func = function(){
    echo 'hi';
}

// call it like this
$cool_func();

Namespacing 在 PHP >= 5.3.0

/* WARNING: this does not work */
/* eval() operates in the global space */
namespace first {
    eval($source_code);
    cool_func();
}

namespace second {
    eval($source_code);
    cool_func();
}

// like this too
first\cool_func();
second\cool_func();

/* this does work */
namespace first {
    function cool_func(){echo 'hi';}
    cool_func();
}

namespace second {
    function cool_func(){echo 'bye';}
    cool_func();
}

对于第二个示例,您需要在需要使用 $cool_func 的每个范围内对 DB 代码进行一次 eval(),见下文:

eval($source_code);

class some_class{
    public function __construct(){
        $cool_func(); // <- produces error
    }
}

$some_class = new some_class(); // error shown

class another_class{
    public function __construct(){
        eval($source_code); // somehow get DB source code in here :)
        $cool_func(); // works
    }
}

$another_class = new another_class(); // good to go

【讨论】:

  • 有 1000s 的代码 sn-ps。没有办法编辑每一个。此外,即使函数具有相同的名称并不意味着它们做同样的事情,所以我不能使用!function_exists
  • 但不是所有这些解决方案都需要编辑数据库中的代码 sn-ps 吗?
  • @user4712608 不,不是命名空间;您只需要更新您的 PHP 代码如何调用来自数据库的 eval()'d 函数。顺便说一句,我添加了第四个选项
  • 要使用命名空间调用函数,我需要在函数名称之前包含命名空间。由于函数是在代码 sn-ps 中创建和调用的,因此需要我编辑代码 sn-ps。
  • @user4712608 再次查看我的编辑。我也无法让选项 4 在我的测试中工作,所以 NVM 关于类选项。
【解决方案2】:

好吧,正如其他人所说,您应该发布代码,以便我们更好地帮助您。但是您可能想研究 PHP OOP,因为您可以为类中的方法提供范围并像这样引用它们:

ClassOne::myFunction();
ClassTwo::myFunction();

查看更多信息:http://php.net/manual/en/language.oop5.paamayim-nekudotayim.php

【讨论】:

  • 有 1000s 的代码 sn-ps。我无法编辑每一个。这需要几个月的时间。
  • 那我猜你搞砸了,因为你不能声明两个同名的函数在 PHP 的相同范围内运行。如果您不想编辑任何代码,您希望如何解决问题?
猜你喜欢
  • 2011-07-17
  • 1970-01-01
  • 2010-11-28
  • 2010-10-17
  • 2014-11-07
  • 1970-01-01
  • 2017-05-22
  • 1970-01-01
相关资源
最近更新 更多