php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #28934 call_user_func_array() and Exceptions
Submitted: 2004-06-27 23:21 UTC Modified: 2005-02-09 01:38 UTC
Votes:22
Avg. Score:4.8 ± 0.5
Reproduced:21 of 21 (100.0%)
Same Version:8 (38.1%)
Same OS:12 (57.1%)
From: richard@php.net Assigned:
Status: Closed Package: Scripting Engine problem
PHP Version: 5.0.0RC3 OS: Linux
Private report: No CVE-ID: None
 [2004-06-27 23:21 UTC] richard@php.net
Description:
------------
When a function called by call_user_func_array() throws an exception, an error appears: "Warning: call_user_func_array() [function.call-user-func-array]: Unable to call babba() in /data/webdev/classes/Tree/demo.php on line 19"

Reproduce code:
---------------
<?php
function babba()
{
    throw new Exception('foo');
}

try {
    call_user_func_array('babba', array());
    
} catch (Exception $e) {
    // Eek
}
?>

Expected result:
----------------
Nothing

Actual result:
--------------
Warning: call_user_func_array() [function.call-user-func-array]: Unable to call babba() in /data/webdev/classes/Tree/demo.php on line 43

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-08-01 23:17 UTC] JustinHagstrom at yahoo dot com
This also happens when an exception is thrown in any callback function.
It is present in the final release of PHP 5 and the snapshots from Aug 01, 2004.
 [2004-08-18 21:34 UTC] phpbugs at d51 dot biz
I ran the following to see if the exception was being thrown.  It is thrown and caught:

Reproduce code:
---------------
<?php
function foo()
{
	throw new Exception('bar');
}

try {
		call_user_func_array('foo', array());
		
} catch (Exception $e) {
	echo $e->getMessage();
}

// Expected output: bar
?>

Actual result:
--------------
Warning: call_user_func_array() [function.call-user-func-array]: Unable to call foo() in /path/to/test.php on line 16
bar


Extended Info:
--------------
I also attempted catching an exception with call_user_func() - it worked as expected producing only "bar".  I also produced an identical outcome when I used a non-empty array as the second argument.

This is most definitely an issue with call_user_func_array().  The following code produces a similar error:


Reproduce code:
---------------
<?php
assert_options( ASSERT_CALLBACK, 'throwException' );
function foo()
{
	assert( false );
	throw new Exception('bar');
}

function throwException( ) {
	throw new Exception('assert');
}

try {
	call_user_func_array('foo', array(0, 1));
} catch (Exception $e) {
	echo $e->getMessage();
}

// Expected Output: assert
?>

Actual results:
---------------
Warning: assert() [function.assert]: Assertion failed in /path/to/test.php on line 7

Warning: call_user_func_array() [function.call-user-func-array]: Unable to call foo() in /path/to/test.php on line 20
assert


More Info:
----------
Bug #29617 seems to be a duplicate of this report.
 [2004-09-13 16:50 UTC] phpbugs at d51 dot biz
--- NOTE ---
This was added to bug #29617 as I didn't realize it had been marked a duplicate.  I'm reposting it here in hopes that it gets picked up.
--- 

I've been running up against this blasted bug for some time in my test scripts - can't test for Exceptions without hard coding it.  Anyhow, I just peeked under the hood and think I've got it squashed.

file: ./ext/standand/basic_functions.c line 1984 - 1985 reads:

	if (call_user_function_ex(EG(function_table), NULL, *func, &retval_ptr,
count, func_params, 0, NULL TSRMLS_CC) == SUCCESS && retval_ptr) {
		COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);

The cause of the bug seems to be the "&& retval_ptr" as an exception doesn't appear to return the same.  It works when you adjust it to work like call_user_func() where it can succeed  even if retval_ptr doesn't exist and/or is false.

Modified ./ext/standand/basic_functions.c line 1984 - 1985 replaced to
1984 - 1984:

	if (call_user_function_ex(EG(function_table), NULL, *func, &retval_ptr,
count, func_params, 0, NULL TSRMLS_CC) == SUCCESS ) {
		if (retval_ptr) {
			COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
		}

I compiled it and ran the test that Benjamin posted on the 16th of Augest.  I did get the correct output (11, 17, & 23).

The modified file is available from:
http://www.domain51productions.com/php/basic_functions.c

In the latest 5.0.X CVS, these lines have moved to 1991 - 1992.

Note: If there's another way to handle submitting a patch, just let me know.

-Travis
 [2004-09-13 17:19 UTC] fch at hexanet dot fr
Same problem with php 5.0.1.
Exception generated by call_user_func_array() was not catched, a warning error was generated instead.
 [2004-09-28 18:26 UTC] phpbugs at d51 dot biz
This is still present in PHP 5.0.2.  I've created a patch file.  Just save it as php-5.0.2/call_user_func_array.patch and run "patch -p0 < call_user_func_array.patch" from within php-5.0.2/.


----- Begin Patch -----
diff -Naur ../php-5.0.2/ext/standard/basic_functions.c ./ext/standard/basic_functions.c
--- ../php-5.0.2/ext/standard/basic_functions.c 2004-08-19 10:15:32.000000000 -0500
+++ ./ext/standard/basic_functions.c    2004-09-24 13:48:58.000000000 -0500
@@ -1988,8 +1988,10 @@
                current++;
        }

-       if (call_user_function_ex(EG(function_table), NULL, *func, &retval_ptr, count, func_params, 0, NULL TSRMLS_CC) == SUC
CESS && retval_ptr) {
-               COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
+       if (call_user_function_ex(EG(function_table), NULL, *func, &retval_ptr, count, func_params, 0, NULL TSRMLS_CC) == SUC
CESS ) {
+               if (retval_ptr) {
+                       COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
+               }
        } else {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s()", name);
        }
----- End Patch -----
 [2005-02-09 01:38 UTC] tony2001@php.net
Fixed in previous releases.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 26 16:01:29 2024 UTC