php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #77321 array_filter combined with references
Submitted: 2018-12-20 09:06 UTC Modified: 2018-12-21 09:27 UTC
From: php at kingsquare dot nl Assigned:
Status: Not a bug Package: Arrays related
PHP Version: 7.0.0 OS:
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: php at kingsquare dot nl
New email:
PHP Version: OS:

 

 [2018-12-20 09:06 UTC] php at kingsquare dot nl
Description:
------------
This is probably on purpose, but there is an undocumented backwards compatibility issue betwee PHP5 and PHP7. I know this might be a bit late to the party, but still.

It involves the differnce in using array_filter and references. 

Test script:
---------------
<?php
// also see https://3v4l.org/Z2HnL
$input = [1, 2];
var_dump(array_filter($input, function(& $value) {
    if ($value % 2 === 0) {
        return false;
    }
    $value++;
    return true;
}));

Expected result:
----------------
As the changelog doesn't seem to mention anything related to this I would expect them to be the same result [(int)2].

Actual result:
--------------
PHP5: [2]
PHP7: [1]


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-12-20 16:56 UTC] requinix@php.net
-Status: Open +Status: Not a bug -PHP Version: 7.3.0 +PHP Version: 7.0.0
 [2018-12-20 16:56 UTC] requinix@php.net
array_filter never supported by-ref values. The fact that it worked in PHP 5 was a bug, and it was fixed in PHP 7 when much of the engine changed.
 [2018-12-20 23:40 UTC] cmb@php.net
Shouldn't we trigger a notice/warning, if we ignore a call-by-ref
declaration?
 [2018-12-21 01:07 UTC] requinix@php.net
I don't think there should be. As far as I know the callback is being called with a reference correctly, however for $input to get the change, it (being the first argument to array_filter) would have to be a reference too.

Just like with a userland implementation, the by-ref $value is working, but since $input isn't a reference the change is happening on a copy. So no warning.

Also like a userland implementation, you can trick the engine by making $input's items references to something else. $input is still a copy but changing $value will work. Like
  $source = [1, 2];
  $input = [&$source[0], &$source[1]];
or
  foreach ($source as $key => $value) {
    $input[$key] =& $source[$key];
  }
 [2018-12-21 09:27 UTC] cmb@php.net
Ah, of course.  Thanks!
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 12:01:31 2024 UTC