php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #63071 func_get_args loses byref information
Submitted: 2012-09-12 11:00 UTC Modified: 2012-09-12 11:15 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: maarten at ba dot be Assigned:
Status: Not a bug Package: Unknown/Other Function
PHP Version: 5.3.16 OS: all
Private report: No CVE-ID: None
 [2012-09-12 11:00 UTC] maarten at ba dot be
Description:
------------
i'm writing code that invokes "hooks" with byref parameters.

but the generalized hook functions lose the byref information due to func_get_args being a copy (but not exact), thus call_user_func_array() (which needs to have references in it's array) can't work.

see shortened example below:

Test script:
---------------
$foo = "foo";
$bar = "bar";
function func_a(&$a, $b) {
  $a = $b;
};
function c() {
  $args = func_get_args();
  call_user_func_array("func_a", $args);
};
c(&$foo, $bar);
var_dump($foo);

Expected result:
----------------
i expected for $foo to have 'bar'

Actual result:
--------------
$foo is still 'foo', and a warning is generated

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-09-12 11:15 UTC] laruence@php.net
-Status: Open +Status: Not a bug
 [2012-09-12 11:15 UTC] laruence@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

"Returns an array in which each element is a copy of the corresponding member of 
the current user-defined function's argument list."

http://us2.php.net/manual/en/function.func-get-args.php
 [2012-09-12 15:18 UTC] maarten at ba dot be
"This function returns a copy of the passed arguments only, ..."

from the same page.

thus an array. it's just that this copied array loses it's byref value for one of the elements in the array...

this makes it impossible to have a hook system where you can also modify a parameter because it's byref
 [2012-09-14 11:13 UTC] maarten at ba dot be
actually, i found a second valid use case for this oversight:

function array_set(&$a, $indexes, &$value) {
  $res = FALSE;
  if (count($indexes) == 0) {
    $a =& $value;
    return $res;
  }
  $i = array_shift($indexes);
  if (!isset($a[$i])) {
    $a[$i] = array();
    $res = TRUE;
  }
  return array_set($a[$i], $indexes, $value) || $res;
}

function set_config() {
  global $config;
  $args = func_get_args();
  $value = array_pop($args);
  return array_set($config, $args, $value);
}

global $config;
$config = array(
  'user' => array(
    'name' => '',
  )
);
set_config('user', 'name', 'FName LName');
var_dump($config);


the way i see it, there are 2 possibilities, really:

A) func_get_args should keep references for references
==> one could argue that byref parameters in the call is a stupid idea

B) functions that are declared with byref parameters should be greedy and force the variables to be a reference, if they must be (and where they come from), and that is what should force one argument to be byref in a func_get_args, even if it wasn't like this.
==> this way, you can safely have no use for byref parameters anymore.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun May 05 11:01:33 2024 UTC