从当前函数中取消设置所有定义的变量

Posted

技术标签:

【中文标题】从当前函数中取消设置所有定义的变量【英文标题】:Unset all defined variables from the current function 【发布时间】:2011-12-12 01:09:01 【问题描述】:

比如我有这个功能:

function foo($whaaaat)

  $var1 = 'a';  
  $a = 1;
  $b = 2;

  ...


  // here unset all variables defined above (including arguments) 
  require 'somefile.php';

那么,我可以在需要点之前取消设置所有这些变量吗?

显然没有在每个变量上手动调用 unset,因为我自己想通了 :)

有这样的功能吗?

【问题讨论】:

为什么要取消设置? @jprofitt:你不觉得这是个无关紧要的问题吗? 没错,但好奇心占了上风。重新阅读我的评论,我并没有真正的意思,听起来像是在判断问题或提问者......诚实! 【参考方案1】:

需要这个,这里的现有答案并没有真正的帮助。以下内容简明扼要且有效:

foreach(get_defined_vars() as $k => $v)
    unset($$k);
unset($k, $v);

如果在这之后调用var_dump(get_defined_vars()),你会得到一个空数组。


注意:除非在全局范围内(问题不是,它在函数中),get_defined_vars 不会返回任何全局变量,所以不需要要过滤或检查任何内容,只需取消设置即可。

【讨论】:

【参考方案2】:

我同意 Whetstone 的观点。 get_defined_vars() 非常适合“多重未设置”技巧。 下面的此方法取消设置所有变量。 除了那些在 foreach 循环内的无名数组中找到的数组

foreach(get_defined_vars() as $k=>$y) 
 if( !in_array( $k, 
 array(
  'myRequredVariableName1',
  'myRequredVariableName2',
  '_ENV',
  '_SESSION',
   '_COOKIE',
  'HTTP_SESSION_VARS',
  'HTTP_COOKIE_VARS'
  )))
   $$k=null; unset($$k); 
    unset($y, $k);
 

// Check for leftovers
header('Content-type:text/plain; charset=utf-8'); 
var_export(get_defined_vars()); 
exit;

这些值实际上是不带'$'的变量名,其中变量变量unset($$k); 匹配REAL 和定义的变量,如果存在则销毁它。因此,通过这种方式,您可以完全控制系统剩余的内容。

注意,一些共享主机设置仅依赖于 _SERVER 超全局变量,因此根本不需要 _ENV、HTTP_SESSION_VARS、HTTP_COOKIE_VARS。很可能您总是希望保留 _COOKIE 和 _SESSION,但不保留 _GET 和 _POST 或 _FILES。决定因人而异。在将这个技巧应用到您的生产环境之前,请自行测试并查看数组中应该包含哪些内容。

【讨论】:

【参考方案3】:

这里有一个解决方案:

echo('Before: ' . $test1 . '<br>');

$vars = array_keys(get_defined_vars());
foreach($vars as $var) 
    if($var == 'GLOBALS' || $var == '_POST' || $var == '_GET' || $var == '_COOKIE' || $var == '_FILES' || $var == '_REQUEST' || $var == '_SERVER' || $var == '_ENV')
        continue;
    unset($$var);

echo('After: ' . $test1 . '<br>');

我的测试输出如下:

之前:这里?

之后:

【讨论】:

您忘记了 REQUEST、SERVER 和 ENV 超全局变量。 感谢您指出这一点,但现在看看 if 声明,肯定会有更好的方法...... 这里的几个答案中的 array_diff() 版本可能已经足够好了。【参考方案4】:

没有内置任何内容,但您可以使用get_defined_vars() 函数获取所有已定义变量的数组,然后使用foreach 循环取消设置它们。这样一来,您就可以在 4 行内完成所有工作,而且非常灵活。

$list_of_vars =  array_diff(get_defined_vars(), $GLOBALS); // Was just get_defined_vars() before Marc B corrected me in his post.
foreach($list_of_vars as $var)
    unset($var);

编辑:正如 Marc B 指出的那样,这也会取消设置您的 $GLOBAL 变量。我已经编辑了我的示例以展示如何正确获取变量列表。

【讨论】:

但是,从 PHP 5.0 开始,这包括 $GLOBALS,因此您将取消设置父范围内的所有内容,包括 SUPERGLOBALS - 非常糟糕。 非常真实,很好。我已经给你的了,并在我的记下了。 这不起作用,因为 unset($var) 是根据需要“取消设置”变量的值,而不是变量的名称或变量本身。【参考方案5】:

假设这些函数内变量都没有声明为全局变量,您可以尝试类似

array_diff(get_defined_vars(), $GLOBALS)

获取局部变量列表,然后循环遍历结果以取消设置。

【讨论】:

var_dump(array_diff(get_defined_vars(), $GLOBALS)); 似乎缺少本地创建的数组... 好点,但是确实缺少本地创建的数组!【参考方案6】:

这可能有效(未经测试):

$allVars = get_defined_vars(); // Returns array of all defined variables
foreach ($allVars as $allVars)  unset($allVars); 

编辑:正如我所说,从未测试过也从未使用过它,但它可以引导 Alex 朝着正确的方向前进。

【讨论】:

但是,从 PHP 5.0 开始,这包括 $GLOBALS,因此您将取消设置父范围内的所有内容,包括 SUPERGLOBALS - 非常糟糕。 这不起作用,因为 unset($allVars) 是“取消设置”变量的值,而不是变量的名称,或者变量本身,因为它需要。【参考方案7】:

您可以将require 包装在anonymous function 中:

function foo($a)
  $b = 2;

  call_user_func(function() 
   require 'somefile.php';
  );

【讨论】:

【参考方案8】:

你可以这样做:

function require_noscope($filename)

    // Required file cannot see variables from other function
    require $filename;


function foo($whaaaat)

  $var1 = 'a';  
  $a = 1;
  $b = 2;
  require_noscope('somefile.php');

【讨论】:

以上是关于从当前函数中取消设置所有定义的变量的主要内容,如果未能解决你的问题,请参考以下文章

在我取消选中收音机并将所有变量设置为未定义后,我的弹出元素将再次出现

“header()” php 函数是不是取消设置全局变量?

如何从 QListView 取消设置所有自定义 QStyledItemDelegates?

取消设置变量与设置为 ''

如何取消设置鱼壳中的变量?

从 cmake 生成的命令中取消设置 cppcheck 分析中的定义