1

对不起,我确定这个答案在互联网上的某个地方(甚至可能是 stackoverflow),但我花了最后一个小时搜索,似乎找不到答案......

PHP 的 extract() 函数是否使用写时复制将变量添加到符号表?

我知道 PHP 函数调用默认情况下都有一个写时复制(除非您通过引用指定),只是对此感到好奇,因为我正在集成一个模板系统,所以我将一大堆变量抓取到一个 $data 数组中,它有时可能会很大,我想知道在包含模板文件之前提取它们是否是解决此问题的最佳方法。

谢谢!

编辑:

澄清:

    $array = array('a' => array(1,2,3), 'b' => array(3,4,5), 'c' => array(6,7,8));
    extract($array);
    //is $a, $b, $c Copy-On-Write at this point? Would be a lot better performance as opposed to allocating 3 new array()'s

    //I would like to avoid having this change the original $array values so using EXTR_REFS is not a good solution for me here if I can avoid it and still keep performance!
    $a = array(3);
4

2 回答 2

3

两个版本都是可能的(提取值并通过引用提取) - 并且很容易展示这两个版本:

function value() {
    $array = array('a' => 1, 'b' => 2);
    extract($array);
    var_dump($a);
    var_dump($b);
    $a = 3;
    $b = 4;
    var_dump($a);
    var_dump($b);
    var_dump($array);
}

function reference() {
    $array = array('a' => 1, 'b' => 2);
    extract($array, EXTR_REFS);
    var_dump($a);
    var_dump($b);
    $a = 3;
    $b = 4;
    var_dump($a);
    var_dump($b);
    var_dump($array);
} 

value();
/* 
int(1)
int(2)
int(3)
int(4)
array(2) {
  ["a"]=>
  int(1)    // original array item is unchanged
  ["b"]=>
  int(2)    // original array item is unchanged
}
*/

reference();
/*
int(1)
int(2)
int(3)
int(4)
array(2) {
  ["a"]=>
  &int(3)    // original array item is changed because it's a reference to the extracted variable
  ["b"]=>
  &int(4)    // original array item is changed because it's a reference to the extracted variable
}

extract()允许第二个参数EXTR_REFS作为选项:

提取变量作为参考。这实际上意味着导入变量的值仍然引用 var_array 参数的值。您可以单独使用此标志,也可以通过对 extract_type 进行 OR'ing 将其与任何其他标志结合使用。

于 2012-11-29T12:11:13.903 回答
0

我会说确实如此,因为EXTR_REFS您可以传递一个标志,将变量提取为引用。如果不使用 COW,那么这将毫无意义。

知道了这一点,如果需要,我会说继续提取,因为您未修改的变量已针对这些变量进行了优化。

于 2012-11-29T06:26:50.527 回答