php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70682 extract() removes any references to array
Submitted: 2015-10-09 21:00 UTC Modified: 2015-10-11 12:13 UTC
From: marc at phpbb dot com Assigned:
Status: Not a bug Package: Arrays related
PHP Version: 7.0Git-2015-10-09 (Git) OS: Ubuntu Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: marc at phpbb dot com
New email:
PHP Version: OS:

 

 [2015-10-09 21:00 UTC] marc at phpbb dot com
Description:
------------
Actual version output (php7 nightly): PHP 7.1.0-dev (cli) (built: Oct  8 2015 19:09:26) ( NTS )

The extract() function removes any references to an array. While the supplied test script works fine on prior PHP versions like 5.5.x and 5.6.x, it does no longer work on the current PHP7 nightly.

Prior to running extract(), the variable $var and its content is a reference to the initial array passed to the test() function. After the call to it, this is no longer the case.
According to debug_zval_dump(), the array itself is still a reference. The content of the array however is not.

I suspect this might have been caused by this as it seems related: https://bugs.php.net/bug.php?id=70250

Test script:
---------------
<?php

	function main()
	{
		$foo = array('meh' => 1);
		var_dump($foo);
		test($foo);
		var_dump($foo);
	}

	function test(&$var)
	{
		$function = function($test) { return array('var' => $test); };
		extract($function($var));
		$var['bar'] = 5;
	}

main();


Expected result:
----------------
array(1) {
  'meh' =>
  int(1)
}
array(2) {
  'meh' =>
  int(1)
  'bar' =>
  int(5)
}

Actual result:
--------------
array(1) {
  ["meh"]=>
  int(1)
}
array(1) {
  ["meh"]=>
  int(1)
}

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-10-10 14:59 UTC] marc at phpbb dot com
Based on a build I compiled myself using the up-to-date git branch, the ticket mentioned in the initial post seems to be unrelated to the current issue. I was also able to reproduce it on 7.0.0-beta1.
 [2015-10-11 12:13 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2015-10-11 12:13 UTC] requinix@php.net
The current behavior seems more correct to me. PHP has had bugs in the past regarding variables being treated as references when they should not have been - especially when indirectly passing values to functions through by-ref parameters. PHP 7 includes a number of changes to how variables and functions work and may have inadvertently fixed this.

Why it's correct?

1. $function does not take an argument by reference, therefore its $test should be a copy. Somehow managing to modify the returned value (be that by regular assignment or by extract() and touching the new values) should not affect the $var that was passed.

2. If the parameter is by-ref then the [var] in the return value from extract() will be the same reference. However the entry in the array is not itself a reference, so when extract() does its work then the extracted variable will still not be a reference to $var.

Changing $function to be
  $function = function(&$test) { return array('var' => &$test); };
produces the expected output.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu May 02 07:01:30 2024 UTC