【问题标题】: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:你不觉得这是个无关紧要的问题吗?
  • 没错,但好奇心占了上风。重新阅读我的评论,我并没有真正的意思,听起来像是在判断问题或提问者......诚实!

标签: php function variables unset


【解决方案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');
        }
        

        【讨论】:

          猜你喜欢
          • 2012-01-31
          • 2011-08-08
          • 1970-01-01
          • 2011-05-31
          • 2017-11-14
          • 2014-12-02
          • 1970-01-01
          • 2020-05-28
          • 1970-01-01
          相关资源
          最近更新 更多