php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51986 array_filter breaks references when a callback is used
Submitted: 2010-06-03 12:28 UTC Modified: 2010-11-02 00:59 UTC
From: daniel dot menard at ehesp dot fr Assigned: dmitry (profile)
Status: Closed Package: Arrays related
PHP Version: 5.3.2 OS: Windows XP
Private report: No CVE-ID: None
 [2010-06-03 12:28 UTC] daniel dot menard at ehesp dot fr
Description:
------------
I have an array and a variable which is a reference on some element in this array:
$arr=array('a'); $ref = &$arr[0]

If I apply array_filter() with a callback like trim() or count() on the array, the reference is broken and $ref is no longer a reference (If I apply array_filter() without a callback, the reference is not altered and the result is correct).

I think that this is a regression introduced in php 5.2.11: with the test script below, 5.2.10 give the good result, 5.2.11 do not.

I also tested with the latest version (5.3.2): same result, reference is broken.

PS: I tested on windows XP with packages php-5.x.y-Win32-VC6-x86.zip provided on this page: http://windows.php.net/downloads/releases/archives/

Test script:
---------------
// Init
$arr = array('some value');
$ref = & $arr[0];

// Change $arr
$arr[0] = 'ONE';
echo 'step 1. $ref is ', ($ref !== 'ONE') ? 'BROKEN' : 'OK', "\n";

// Apply array_filter (without callback) and change $arr
array_filter($arr);
$arr[0] = 'TWO';
echo 'step 2. $ref is ', ($ref !== 'TWO') ? 'BROKEN' : 'OK', "\n";

// Apply array_filter (with a callback) then change $arr
array_filter($arr,'trim');
$arr[0] = 'THREE';
echo 'step 3. $ref is ', ($ref !== 'THREE') ? 'BROKEN' : 'OK', "\n";

Expected result:
----------------
step 1. $ref is OK
step 2. $ref is OK
step 3. $ref is OK

Actual result:
--------------
step 1. $ref is OK
step 2. $ref is OK
step 3. $ref is BROKEN

Patches

bug_51986_5_3 (last revision 2010-09-29 21:12 UTC by cataphract@php.net)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-06-03 13:00 UTC] sjoerd@php.net
Use a reference in your callback function:

function my_trim(& $a)
{
	return trim($a);
}
 [2010-06-03 14:29 UTC] daniel dot menard at ehesp dot fr
Thanks for your comment: your workaround works.

However, having to redefine standard php functions like trim() or count() just to be able to use them with array_filter() is not very convenient, is it?

The fact is that the function behaviour changed in a "revision release" which should not have broken my code...  

;-)
 [2010-09-29 13:05 UTC] cataphract@php.net
-Status: Open +Status: Verified -Assigned To: +Assigned To: cataphract
 [2010-09-29 13:05 UTC] cataphract@php.net
Reproducible on PHP 5.3, but not on trunk.
 [2010-09-29 23:11 UTC] cataphract@php.net
-Status: Verified +Status: Analyzed -Assigned To: cataphract +Assigned To: dmitry
 [2010-09-29 23:11 UTC] cataphract@php.net
Sorry, it doesn't work on trunk, it works on my patched trunk :p

Fixing bug #52940 would fix this. However, the patch for that bug has one effect that changes the current behavior of call_user_func_array (removes check for internal function) and another change when the refcount of the zval is <= 1 and it's a reference (a rare case).

Attached a patch that changes as little as possible, yet fixes this bug.
 [2010-09-29 23:12 UTC] cataphract@php.net
The following patch has been added/updated:

Patch Name: bug_51986_5_3
Revision:   1285794735
URL:        http://bugs.php.net/patch-display.php?bug=51986&patch=bug_51986_5_3&revision=1285794735
 [2010-11-02 00:59 UTC] felipe@php.net
-Status: Analyzed +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Apr 28 07:01:30 2024 UTC