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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: daniel dot menard at ehesp dot fr
New email:
PHP Version: OS:

 

 [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)

Pull Requests

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-2025 The PHP Group
All rights reserved.
Last updated: Wed Apr 02 18:01:31 2025 UTC