Discussion:
#50394 [Opn->Fbk]: Reference argument converted to value in __call
(too old to reply)
j***@php.net
2009-12-07 07:47:52 UTC
Permalink
ID: 50394
Updated by: ***@php.net
Reported By: tstarling at wikimedia dot org
-Status: Open
+Status: Feedback
Bug Type: Scripting Engine problem
Operating System: Linux
PHP Version: 5.3.1
New Comment:

Regression from what version?


Previous Comments:
------------------------------------------------------------------------

[2009-12-07 01:40:18] tstarling at wikimedia dot org

Description:
------------
This is a regression in the PHP 5.3.1 release. When you call a __call()
function with a reference parameter, it is silently converted to a
value, by the time it reaches the second argument to __call().

This breaks MediaWiki and has no obvious workaround.

Reproduce code:
---------------
function foo( &$x ) {}

class Proxy {
function __call( $name, $args ) {
debug_zval_dump( $args );
call_user_func_array( 'foo', $args );
}
}

$arg = 1;
$args = array( &$arg );
$proxy = new Proxy;
call_user_func_array( array( &$proxy, 'bar' ), $args );


Expected result:
----------------
PHP 5.3.0 produces:

array(1) refcount(4){
[0]=>
&long(1) refcount(5)
}


Actual result:
--------------
array(1) refcount(4){
[0]=>
long(1) refcount(3)
}

Warning: Parameter 1 to foo() expected to be a reference, value given
in /home/tstarling/src/php/stuff/test-reference-call.php on line 8



------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=50394&edit=1
j***@php.net
2009-12-07 07:49:07 UTC
Permalink
ID: 50394
Updated by: ***@php.net
-Summary: Reference argument converted to value in __call
Reported By: tstarling at wikimedia dot org
-Status: Feedback
+Status: Open
Bug Type: Scripting Engine problem
Operating System: Linux
PHP Version: 5.3.1
New Comment:

Nevermind, I didn't notice the versioin expected result. :)


Previous Comments:
------------------------------------------------------------------------

[2009-12-07 07:47:52] ***@php.net

Regression from what version?

------------------------------------------------------------------------

[2009-12-07 01:40:18] tstarling at wikimedia dot org

Description:
------------
This is a regression in the PHP 5.3.1 release. When you call a __call()
function with a reference parameter, it is silently converted to a
value, by the time it reaches the second argument to __call().

This breaks MediaWiki and has no obvious workaround.

Reproduce code:
---------------
function foo( &$x ) {}

class Proxy {
function __call( $name, $args ) {
debug_zval_dump( $args );
call_user_func_array( 'foo', $args );
}
}

$arg = 1;
$args = array( &$arg );
$proxy = new Proxy;
call_user_func_array( array( &$proxy, 'bar' ), $args );


Expected result:
----------------
PHP 5.3.0 produces:

array(1) refcount(4){
[0]=>
&long(1) refcount(5)
}


Actual result:
--------------
array(1) refcount(4){
[0]=>
long(1) refcount(3)
}

Warning: Parameter 1 to foo() expected to be a reference, value given
in /home/tstarling/src/php/stuff/test-reference-call.php on line 8



------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=50394&edit=1
s***@php.net
2009-12-09 23:10:19 UTC
Permalink
ID: 50394
Updated by: ***@php.net
Reported By: tstarling at wikimedia dot org
-Status: To be documented
+Status: Open
Bug Type: Scripting Engine problem
Operating System: Linux
PHP Version: 5.3.1


Previous Comments:
------------------------------------------------------------------------

[2009-12-08 04:46:10] tstarling at wikimedia dot org

For the record, I've isolated this further, and the annotation suggests
it was introduced in r287466 by stas in the course of fixing another
bug.

------------------------------------------------------------------------

[2009-12-07 18:48:45] ***@php.net

Feel free.

------------------------------------------------------------------------

[2009-12-07 09:51:29] tstarling at wikimedia dot org

I fail to see the relationship with bug #49946. That's just someone
reporting behaviour as a bug which was clearly documented in the 5.3
release notes as a deliberate change. I'm not complaining about the
warning, which I just added to demonstrate the problem. I'm not
complaining about the new behaviour of zend_call_function() as of PHP
5.3.0, I'm complaining about the lost reference in __call in PHP 5.3.1.

The fact that the reference is lost makes it impossible for __call to
implement an "out" parameter.

Your own code still demostrates the bug nicely, if you change the $arg
in the foreach to &$arg and then make foo() attempt to modify its
parameter:

<?php

function foo( &$x ) {
$x = 2;
}

class Proxy {
function __call( $name, $args ) {
debug_zval_dump( $args );

$pass = array();
foreach ($args as &$arg)
$pass[] =& $arg;

call_user_func_array( 'foo', $pass );
}
}

$arg = 1;
$args = array( &$arg );
$proxy = new Proxy;
call_user_func_array( array( $proxy, 'bar' ), $args );
debug_zval_dump( $arg );

?>

The final debug_zval_dump() produces 2 in PHP 5.3.0 and 1 in PHP 5.3.1.


Jani, I seem to remember that last time our paths crossed, the issue
ended up on php-dev:

http://marc.info/?l=php-internals&m=124226646727485&w=2

I'm happy to take this one there as well if necessary.

------------------------------------------------------------------------

[2009-12-07 08:00:05] ***@php.net

See bug #49946 and Johannes' comment. This works (in both 5.3 and
5.2):

<?php

function foo( &$x ) {}

class Proxy {
function __call( $name, $args ) {
debug_zval_dump( $args );

$pass = array();
foreach ($args as $arg)
$pass[] =& $arg;

call_user_func_array( 'foo', $pass );
}
}

$arg = 1;
$args = array( &$arg );
$proxy = new Proxy;
call_user_func_array( array( $proxy, 'bar' ), $args );

?>

This really should be documented on the manual at
http://php.net/call_user_func_array


------------------------------------------------------------------------

[2009-12-07 01:40:18] tstarling at wikimedia dot org

Description:
------------
This is a regression in the PHP 5.3.1 release. When you call a __call()
function with a reference parameter, it is silently converted to a
value, by the time it reaches the second argument to __call().

This breaks MediaWiki and has no obvious workaround.

Reproduce code:
---------------
function foo( &$x ) {}

class Proxy {
function __call( $name, $args ) {
debug_zval_dump( $args );
call_user_func_array( 'foo', $args );
}
}

$arg = 1;
$args = array( &$arg );
$proxy = new Proxy;
call_user_func_array( array( &$proxy, 'bar' ), $args );


Expected result:
----------------
PHP 5.3.0 produces:

array(1) refcount(4){
[0]=>
&long(1) refcount(5)
}


Actual result:
--------------
array(1) refcount(4){
[0]=>
long(1) refcount(3)
}

Warning: Parameter 1 to foo() expected to be a reference, value given
in /home/tstarling/src/php/stuff/test-reference-call.php on line 8



------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=50394&edit=1
tstarling at wikimedia dot org
2009-12-08 04:46:11 UTC
Permalink
ID: 50394
User updated by: tstarling at wikimedia dot org
Reported By: tstarling at wikimedia dot org
Status: To be documented
-Bug Type: Documentation problem
+Bug Type: Scripting Engine problem
Operating System: Linux
PHP Version: 5.3.1
New Comment:

For the record, I've isolated this further, and the annotation suggests
it was introduced in r287466 by stas in the course of fixing another
bug.


Previous Comments:
------------------------------------------------------------------------

[2009-12-07 18:48:45] ***@php.net

Feel free.

------------------------------------------------------------------------

[2009-12-07 09:51:29] tstarling at wikimedia dot org

I fail to see the relationship with bug #49946. That's just someone
reporting behaviour as a bug which was clearly documented in the 5.3
release notes as a deliberate change. I'm not complaining about the
warning, which I just added to demonstrate the problem. I'm not
complaining about the new behaviour of zend_call_function() as of PHP
5.3.0, I'm complaining about the lost reference in __call in PHP 5.3.1.

The fact that the reference is lost makes it impossible for __call to
implement an "out" parameter.

Your own code still demostrates the bug nicely, if you change the $arg
in the foreach to &$arg and then make foo() attempt to modify its
parameter:

<?php

function foo( &$x ) {
$x = 2;
}

class Proxy {
function __call( $name, $args ) {
debug_zval_dump( $args );

$pass = array();
foreach ($args as &$arg)
$pass[] =& $arg;

call_user_func_array( 'foo', $pass );
}
}

$arg = 1;
$args = array( &$arg );
$proxy = new Proxy;
call_user_func_array( array( $proxy, 'bar' ), $args );
debug_zval_dump( $arg );

?>

The final debug_zval_dump() produces 2 in PHP 5.3.0 and 1 in PHP 5.3.1.


Jani, I seem to remember that last time our paths crossed, the issue
ended up on php-dev:

http://marc.info/?l=php-internals&m=124226646727485&w=2

I'm happy to take this one there as well if necessary.

------------------------------------------------------------------------

[2009-12-07 08:00:05] ***@php.net

See bug #49946 and Johannes' comment. This works (in both 5.3 and
5.2):

<?php

function foo( &$x ) {}

class Proxy {
function __call( $name, $args ) {
debug_zval_dump( $args );

$pass = array();
foreach ($args as $arg)
$pass[] =& $arg;

call_user_func_array( 'foo', $pass );
}
}

$arg = 1;
$args = array( &$arg );
$proxy = new Proxy;
call_user_func_array( array( $proxy, 'bar' ), $args );

?>

This really should be documented on the manual at
http://php.net/call_user_func_array


------------------------------------------------------------------------

[2009-12-07 01:40:18] tstarling at wikimedia dot org

Description:
------------
This is a regression in the PHP 5.3.1 release. When you call a __call()
function with a reference parameter, it is silently converted to a
value, by the time it reaches the second argument to __call().

This breaks MediaWiki and has no obvious workaround.

Reproduce code:
---------------
function foo( &$x ) {}

class Proxy {
function __call( $name, $args ) {
debug_zval_dump( $args );
call_user_func_array( 'foo', $args );
}
}

$arg = 1;
$args = array( &$arg );
$proxy = new Proxy;
call_user_func_array( array( &$proxy, 'bar' ), $args );


Expected result:
----------------
PHP 5.3.0 produces:

array(1) refcount(4){
[0]=>
&long(1) refcount(5)
}


Actual result:
--------------
array(1) refcount(4){
[0]=>
long(1) refcount(3)
}

Warning: Parameter 1 to foo() expected to be a reference, value given
in /home/tstarling/src/php/stuff/test-reference-call.php on line 8



------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=50394&edit=1
david at tuxteam dot com
2010-09-03 23:16:50 UTC
Permalink
Edit report at http://bugs.php.net/bug.php?id=50394&edit=1

ID: 50394
Comment by: david at tuxteam dot com
Reported by: tstarling at wikimedia dot org
Summary: Reference argument converted to value in __call
Status: Closed
Type: Bug
Package: Scripting Engine problem
Operating System: Linux
PHP Version: 5.3.1
Assigned To: pajoye
Block user comment: N

New Comment:

This seems to be an issue for Drupal modules as well. This is a
significant problem for running Drupal on PHP 5.3.


Previous Comments:
------------------------------------------------------------------------
[2010-08-10 09:14:45] parktrip at gmail dot com

I have the same problem with mediawiki 1.15.5 and PHP 5.3.2 (lastest
version from Zend Server)
So is this a MW problem or PHP ?

------------------------------------------------------------------------
[2010-07-23 01:09:33] heis dot turtlemad at gmail dot com
Mediawiki is wrong in their comments.
Not quite true.
There is a regression which was fixed in 5.3.2,
so upgrade to 5.3.2 is the right way to do it.
Upgrading to 5.3.2 doesn't solve the issue, running the following
softwares:
FreeBSD 8/Nginx/MediaWiki 1.15.4
Any call to a Mediawiki extension fails on the following error:
<Parameter n to xxx expected to be a reference, value given in yyy>

Downgrading to 5.2 is actually the only way to get rid of this.

------------------------------------------------------------------------
[2010-06-06 19:04:27] ***@php.net

Mediawiki is wrong in their comments. There is a regression which was
fixed in 5.3.2, so upgrade to 5.3.2 is the right way to do it.

No need of further comments tho', the issue is fixed.

Thanks for your feedbacks.

------------------------------------------------------------------------
[2010-06-06 18:55:37] PandoraBox2007 at gmail dot com

install-utils.inc

set comments

/*
$test = new PhpRefCallBugTester;
$test->execute();
if ( !$test->ok ) {
echo "PHP 5.3.1 is not compatible with MediaWiki due to a bug
involving\n" .
"reference parameters to __call. Upgrade to PHP 5.3.2 or higher, or
\n" .
"downgrade to PHP 5.3.0 to fix this.\n" .
"ABORTING (see http://bugs.php.net/bug.php?id=50394 for details)\n";
die( -1 );
}
*/

------------------------------------------------------------------------
[2010-06-06 18:12:56] PandoraBox2007 at gmail dot com

fuccking PHP 5.3.2-SVN

not working this shit

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

http://bugs.php.net/bug.php?id=50394
--
Edit this bug report at http://bugs.php.net/bug.php?id=50394&edit=1
Loading...