ID:               29493
 User updated by:  msm at manley dot org
 Reported By:      msm at manley dot org
 Status:           Open
 Bug Type:         Unknown/Other Function
 Operating System: Linux, FreeBSD
 PHP Version:      5.0.0
 New Comment:

I shortened my testcases down to the following:

<?php
rc1(); rc2(); rc3();

function rc1()
{
  echo "\n\n1: array copy by value\n";
  $a = array( 'foo' => 'bar');
  $b = $a;
  $b['foo'] = 'diff';
  print_r($a);
  echo "\n-----\nnow extract from a with EXTR_REFS\n";
  extract($a,EXTR_REFS);
  echo "post extract, foo = $foo\n";
  $foo = 'noo';
  echo "post reassign, foo = $foo\n";
  print_r($a);
  print_r($b);
}

function rc2()
{
  echo "\n\n2: array copy by reference\n";
  $a = array( 'foo' => 'bar');
  $b =& $a;
  print_r($a);
  echo "\n-----\nnow extract from a with EXTR_REFS\n";
  extract($a,EXTR_REFS);
  echo "post extract, foo = $foo\n";
  $foo = 'noo';
  echo "post reassign, foo = $foo\n";
  print_r($a);
}

function rc3()
{
  echo "\n\n3: array copy by reference then unset copy\n";
  $a = array( 'foo' => 'bar');
  $b =& $a;
  unset($b);
  print_r($a);
  echo "\n-----\nnow extract from a with EXTR_REFS\n";
  extract($a,EXTR_REFS);
  echo "post extract, foo = $foo\n";
  $foo = 'noo';
  echo "post reassign, foo = $foo\n";
  print_r($a);
}
?>

Testcases 1 and 3 pass - $foo is a ref to $a['foo']. Testcase 2 fails
-- $foo does not appear to be a ref to $a['foo'].


Previous Comments:
------------------------------------------------------------------------

[2004-08-03 18:18:25] msm at manley dot org

Ignore testcase #2. The behavior there is correct. PHP's lazy copy
behavior, in combination with modifying the array via the ref to an
entry not triggering the copy, threw me.

So it would appear that there is only an issue with extract(array,
EXTR_REFS) when there are multiple entries in the symbol table for that
array, which would be the first and third testcases.

I've looked at ext/standard/array.c and the extract() code, but I'm not
familar enough with the code in there to figure out what's wrong.

------------------------------------------------------------------------

[2004-08-02 17:38:11] msm at manley dot org

Description:
------------
Is there an issue with extract() using EXTR_REFS when more than one
symbol points to an array variable?

EXTR_REF "extracts variables as references. This effectively means that
the values of the imported variables are still referencing the values of
the var_array parameter." (from
http://us2.php.net/manual/en/function.extract.php)

>From some experiments, I think that this function has issues when you
pass it an array that has been given a reference or pass in a reference
to an array itself. 

It three of the four testcases shown below, it would appear that the
extracted variable $foo is NOT actually a reference into $array['foo']
after the extract() call.

PHP does lazy copies on arrays. Does modifying an array via a reference
to one of the array's members not trigger the lazy copy? This is not the
bug (and makes sense to me), though it certainly added to the confusion
trying to figure out what was happenning here.

The testcases return the same results under PHP 4.3.4, PHP 4.3.8 and
PHP 5.0.0 on all the FreeBSD, Linux and Windows systems I have access
to.

Reproduce code:
---------------
I describe four testcases and their output at
http://www.sitepoint.com/forums/showthread.php?p=1329965

Sorry, the testcases are longer than 20 lines, all total. In summary:

1) Copy array by reference  -- $array_b =& $array_a -- and then
extract(array, EXTR_REFS) from each.

2) Copy array by value -- $array_b = $array_a -- and then
extract(array, EXTR_REFS) from each.

3) Copy array by reference, then modify a value in the array, then
extract(array, EXTR_REFS) from each.

4) Copy array by value, then modify a value in the array (triggering
the lazy copy), then extract(array, EXTR_REFS) from each.

Expected result:
----------------
In each testcase, given an array ('foo' => 'value') I expect to see a
variable $foo that is a reference to $array['foo'] and when I change
$foo's value, the value of $array['foo'] should change accordingly.

Actual result:
--------------
Is the first three testcases $foo appears not to be a reference to
$array_a['foo'] or $array_b['foo']. 

In the fourth testcase, extract(array, EXTR_REFS) performs as expected.



------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=29493&edit=1

Reply via email to