在PHP中运行时删除函数(没有runkit扩展)

Ale*_*exV 24 php function

我知道这个问题看起来很丑陋和奇怪,但是有没有办法在运行时删除PHP中的函数?

我有一个在"if"块中声明的递归函数,并希望该函数仅在"if"块中"有效".我不希望在此块之外调用此函数.

我发现了runkit_function_remove,但我的Web主机上没有启用runkit.还有另一种方法吗?

顺便说一下,我只支持PHP 5.1.0.

编辑:我知道我的问题是hacky,但这是我想要做的事情:

if (function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc())
{
    function stripslashes_deep($value)
    {
        return is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
    }

    $_POST = array_map('stripslashes_deep', $_POST);
    $_GET = array_map('stripslashes_deep', $_GET);
    $_COOKIE = array_map('stripslashes_deep', $_COOKIE);
    $_REQUEST = array_map('stripslashes_deep', $_REQUEST);

    //runkit_function_remove('stripslashes_deep');
}
Run Code Online (Sandbox Code Playgroud)

由于"stripslashes_deep"只会在魔术引号是,我想摆脱它,当我用它做.我不希望人们依赖一个并不总是存在的功能.我希望现在更清楚了.非hacky解决方案建议也是受欢迎的!

Gor*_*don 20

PHP手册功能:

PHP中的所有函数和类都具有全局范围 - 即使它们是在内部定义的,也可以在函数外部调用它们,反之亦然.[...] PHP不支持函数重载,也不可能取消定义或重新定义以前声明的函数.

例外是通过runkit.但是,您可以将您的函数定义为匿名函数,unset并在运行它之后将其定义为,例如

if (function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc())
    $fn = create_function('&$v, $k', '$v = stripslashes($v);'); 
    array_walk_recursive(array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST), $fn);
    unset($fn);
}
Run Code Online (Sandbox Code Playgroud)

一些评论员正确指出(但现在不再是PHP中的问题了),你不能在自己内部调用匿名函数.通过使用array_walk_recursive你可以解决这个限制.就个人而言,我只想创建一个常规函数,而不是删除它.它不会伤害任何人.只要给它一个正确的名字,比如stripslashes_gpc_callback.

注意:评论后编辑和浓缩


Sim*_*gét 6

从PHP 5.3开始,您可以使用匿名函数:

$anonymous_function = function($value){
  // do stuff
};
Run Code Online (Sandbox Code Playgroud)

像这样称呼它:

$returned_value = $anonymous_function('some parameter');
Run Code Online (Sandbox Code Playgroud)

要删除该函数,只需取消设置该变量:

unset($anonymous_function);
Run Code Online (Sandbox Code Playgroud)

以下是如何实现您的功能的示例:

$stripslashes_deep = function (&$object){
  global $stripslashes_deep;
  if(is_array($object)) 
    foreach($object as &$value){ 
      if(is_array($value)) 
        $stripslashes_deep($value);
      else
        $value = stripslashes($value);
    }
};
Run Code Online (Sandbox Code Playgroud)

匿名函数没有名称.因此,您不能使用array_map,因为它只会将函数名称作为参数.

匿名函数具有可变范围.因此,您必须将包含函数的变量声明为global,以便在递归函数中到达它.

不幸的是,如果在匿名函数中定义常规函数,即使在取消设置变量之后,它也将全局可用.(我真的没有看到它的好处.我希望以后纠正是一个大错:-)

  • 我认为您在这里没有要点:),但您对分号是正确的。谢谢。 (2认同)