【问题标题】:unset extract variables in php from within class methodunset 从类方法中提取 php 中的变量
【发布时间】:2014-09-11 09:04:24
【问题描述】:
<?php
namespace foo;
class bar{
  public static function runner( $data )
  {

     extract ($data);

     foreach( $elements as $element )
     {
        $varsToWipe = array_keys($element);
        extract( $element );

        /*
            bunch of code using the variables extracted from $element, eg   if( isset($runnerSpeed) )
        */

        //now i want to be able to unset all the elements set from the extract within the foreach loop
        foreach( $varsToWipe as $var )
        {
            //but what goes here in the unset function?
            \unset(  );
        }
     }

  }
}

如何在 runner 方法中取消设置从 foreach 循环中提取的变量?

$data 的内容可能会有所不同,需要取消设置 var,以免在下一次循环迭代中再次使用。我知道我可以引用数组本身,但如果这可行的话,写起来会更快......

谢谢, 约翰

一个更简单的 foreach 示例:

$array = range(0,6);
$i = 0;
foreach( $array as $a )
{
   echo $i.' ';
   if( $i == 0 )
  {
    $egg = true;
  }
  ++$i;
  if( isset($egg) )
  {
     echo 'eggs ';
  }
}

将打印

0个鸡蛋1个鸡蛋2个鸡蛋3个鸡蛋4个鸡蛋5个鸡蛋6个鸡蛋

然后,您可以从全局变量中删除 $egg,因为它就是它所在的位置:

$array = range(0,6);

$i = 0;

foreach( $array as $a )
{
   echo $i.' ';
   if( $i == 0 )
  {
    $egg = true;
  }
  else
  {
     unset( $GLOBALS['egg'] );
  }
  ++$i;
  if( isset($egg) )
  {
     echo 'eggs ';
  }
}

现在它会打印出来:

0 个鸡蛋 1 2 3 4 5 6

但是当你在一个类方法中时你会取消设置什么,变量实际存储在哪里?

【问题讨论】:

  • 函数执行终止时,提取的变量应该自动超出范围
  • 函数执行,是否包括foreach函数?
  • 不,这是 runner 函数终止的时间:标准 PHP 变量范围规则
  • 是的,所以 foreach 循环的第二次迭代.. 在第一次迭代中设置并且在第二次迭代中未重置的任何 var 都将因此持续存在。这就是我要清理的内容..还是我弄错了?
  • 你为什么要首先使用extract:它会导致重大问题,因为你不知道变量叫什么:你为什么不能简单地使用$data数组第一名。

标签: php unset


【解决方案1】:

现在已经很晚了,但仅供参考。

您可以使用以下命令直接取消设置()它们:

unset($$var);

提取物的作用相当于:

foreach($arr as $key => $value) {
    $$key = $value;
}

所以要取消设置:

foreach(array_keys($arr) as $key) {
    unset($$key);
}

但是就像提到的那样,您不需要 unset() 它们,因为它们会在函数完成时被删除,因为它们将超出范围。

此外,extract() 完全没问题,因为它(很可能)不会复制数据值,它只是为每个数组键创建新符号。如果您实际修改它,PHP 只会在内部复制这些值。带引用计数的写时复制。

当然,您可以在对大型数组执行 extract() 之前和之后使用 memory_get_usage() 进行测试。

【讨论】:

    【解决方案2】:

    首先不要使用extract() 函数,而是简单地遍历给定的数组。

    <?php
    
    class Foo {
    
      public function runner($data) {
        foreach ($data as $delta => $element) {
          if ($element === "something") {
            // do something
          }
        }
      }
    
    }
    

    当然,您现在可以取消设置数组中的某些内容,但您为什么要这样做呢?我看不出一个原因,因为数组没有通过引用传递,也没有在循环之后使用,所以它会超出范围,只是被垃圾收集器收集。

    如果是嵌套数组:

    foreach ($data as $delta => $element) {
      if (is_array($element)) {
        foreach ($element as $deltaInner => $elementInner) {
          // ...
    

    【讨论】:

    • 当上面代码中的 $element 是一个 assoc 数组时,这实际上不起作用。
    • 如果你有嵌套数组嵌套循环,我会用嵌套数组扩展答案。
    • 嗯,看来值得一试。对我来说理想的解决方案是能够提取 $delta 然后在迭代结束时取消设置从 $delta 提取的所有变量。
    • 我知道如何使用 foreach 循环。无论如何我不会在最终代码中使用 foreach 循环。与 std for 相比,开销要大得多。我只是在寻找与 extract 完全相反的答案:webconfiguration.blogspot.co.uk/2012/04/php-and-foreach.html
    • 您只需添加一个几乎没有必要的附加函数调用。直接启动循环是您最快的选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-23
    • 2010-11-19
    • 2016-07-31
    相关资源
    最近更新 更多