search for in the  
<Function handlingcall_user_func>
Last updated: Thu, 19 May 2005

call_user_func_array

(PHP 4 >= 4.0.4, PHP 5)

call_user_func_array --  Call a user function given with an array of parameters

Description

mixed call_user_func_array ( callback function, array param_arr )

Call a user defined function given by function, with the parameters in param_arr. For example:

Example 1. call_user_func_array() example

<?php
function debug($var, $val)
{
   echo
"***DEBUGGING\nVARIABLE: $var\nVALUE:";
   if (
is_array($val) || is_object($val) || is_resource($val)) {
      
print_r($val);
   } else {
       echo
"\n$val\n";
   }
   echo
"***\n";
}

$c = mysql_connect();
$host = $_SERVER["SERVER_NAME"];

call_user_func_array('debug', array("host", $host));
call_user_func_array('debug', array("c", $c));
call_user_func_array('debug', array("_POST", $_POST));
?>

See also call_user_func(), and information about the callback type



User Contributed Notes
call_user_func_array
taylor
07-May-2005 05:04
<?php
  
/**
     * Create an object of a specified type using an array as the parameters
     * to the constructor.  NOTE: does not maintain proper
     * types for the arguments.  They are all converted to strings.
     * @param $type Type type of object to create (class name)
     * @param $args The arguments to pass to the constructor
     */
  
function createObjArray($type, $args=array()) {
       if ( !
class_exists($type) ) {
           return
NULL;
       }
      
      
// build argument list; be sure to escape string delimeters
      
$func = create_function('$str', 'return str_replace("\'","\\\'",$str);');
      
$sargs = "'" . join( "','", array_map($func,$args) ). "'";
      
      
// build & eval code; return result
      
$seval = "return new $type($sargs);";
       return eval(
$seval);
   }
?>
amer at o2 dot pl
20-Jan-2005 04:44
PLS notice that "patripaq at hotmail dot com" 's code will be valid if B EXTENDS A...
<?php
class B extends A{
...
}
?>
there>>"What I wanted to do is create an object that can manage any number and any kind of parameters."

BUT IT IS NOT A POINT AT ALL

If you need to call just function with parameters:
call_user_func_array('Foo',$args);

If you need to call CLASS method (NOT object):
call_user_func_array(array('class', 'Foo'),$args);

If you need to call OBJECT method:
call_user_func_array(array(&$Object, 'Foo'),$args);

If you need to call method of object of object:
call_user_func_array(array(&$Object->Object, 'Foo'),$args);

If you need to call object method from within the very same object (NOT CLASS!):
call_user_func_array(array(&$this, 'Foo'),args);

The call_user_func_array ITSELF can manage any number and any kind of parameters. It can handle ANY FUNCTION too as it is defined and that maybe partipaq wanted to manage.

What You actually need is object composition not inheritance. Make an instance from arguments.
<?php
...
class
B{
   function
__construct() {
    
$args = func_get_args(); // Get arguments
    
$this->OBJ = new A($args);
    
call_user_func_array(array(&$this->OBJ, 'A'), $args );
   }
}
?>
Then there can be any number and any type of created object B parameters
james at gogo dot co dot nz
21-Nov-2004 07:19
Be aware the call_user_func_array always returns by value, as demonstrated here...

<?php   
  
function &foo(&$a)
   {
     return
$a;
   }
  
  
$b = 2;
  
$c =& call_user_func_array('foo', array(&$b));
  
$c++;
   echo
$b . ' ' . $c;   
?>

outputs "2 3", rather than the expected "3 3".

Here is a function you can use in place of call_user_func_array which returns a reference to the result of the function call.

<?php
  
function &ref_call_user_func_array($callable, $args)
   {
       if(
is_scalar($callable))
       {
          
// $callable is the name of a function
          
$call = $callable;
       }
       else
       {
           if(
is_object($callable[0]))
           {
              
// $callable is an object and a method name
              
$call = "\$callable[0]->{$callable[1]}";
           }
           else
           {
              
// $callable is a class name and a static method
              
$call = "{$callable[0]}::{$callable[1]}";
           }
       }
      
      
// Note because the keys in $args might be strings
       // we do this in a slightly round about way.
      
$argumentString = array();
      
$argumentKeys = array_keys($args);
       foreach(
$argumentKeys as $argK)
       {
          
$argumentString[] = "\$args[$argumentKeys[$argK]]";
       }
      
$argumentString = implode($argumentString, ', ');
      
// Note also that eval doesn't return references, so we
       // work around it in this way...   
      
eval("\$result =& {$call}({$argumentString});");
       return
$result;
   }
?>
php at pjt33 dot f2g dot net
25-Oct-2004 07:31
Note that, although it doesn't say so here or in the linked page with information about the callback type, the changelog ( http://www.php.net/ChangeLog-4.php#4.0.5 ) states that call_user_func_array in PHP 4.0.4 won't take an array as the first argument. This was added in 4.0.5.
patripaq at hotmail dot com
06-Aug-2004 05:49
I just started using PHP 5.0 and, so far, I'm loving it !  However, I had a problem the other day and thought it would be a good idea to inform other programmers about the solution I found to get around it.  It concerns the new __constructor() function and the call_user_func_array() function.  What I wanted to do is create an object that can manage any number and any kind of parameters.  Here's the problematic code:

<?php
//--------------------------
class A {
  function
__construct() {
  
$args = func_get_args(); // Get arguments
   // Class initialization...
 
}
  function
A() {
  
$args = func_get_args(); // Get arguments
  
call_user_func_array( array(&$this, '__construct'), $args ); // Infinite loop to B::__construct()...
 
}
}

class
B {
  function
__construct() {
  
$args = func_get_args(); // Get arguments
  
call_user_func_array( array(&$this, 'A'), $args ); // Initialize parent with arguments
   // Class initialization...
 
}
}

$obj = new B( 'param1', 'param2' );
//--------------------------
?>

I suppose you can guess where the problem is located... In the A::A() function, the call to __construct() using call_user_func_array() is redirected to B::__construct() instead of A::__construct().  The only way I found to specify which constructor function I wanted to call was to stop using A::__construct() and use the old fashion constructor instead.  If anyone can find a better way, feel free to add comments.  Here's my solution.  Hope it helps anyone.

<?php
//--------------------------
class A {
  function
A() {
  
$args = func_get_args(); // Get arguments
   // Class initialization...
 
}
}

class
B {
  function
__construct() {
  
$args = func_get_args(); // Get arguments
  
call_user_func_array( array(&$this, 'A'), $args ); // Initialize parent with arguments
   // Class initialization...
 
}
}

$obj = new B( 'param1', 'param2' );
//--------------------------
?>
hong dot nguyen at k-edge dot com
02-Apr-2004 11:37
call_user_func_array can pass parameters as reference:

<?php
call_user_func_array
(array(&$obj,$method),array(&$arg1,$arg2,$arg3))
?>

Use it as work-around for "Call-time pass-by-reference has been deprecated".
mightye (at) mightye (dot) org
12-Mar-2004 11:19
From what I can tell, call_user_func_array *always* passes by value, even if the function asks for a reference (perhaps it duplicates the args before passing them?).
adamh at densi dot com
31-Jul-2003 01:58
call_user_func_array() is nifty for calling PHP functions which use variable argument length. For example:

<?php
$array
= array(
 array(
"foo", "bar"),
 array(
"bat", "rat"),
);

$values = call_user_func_array("array_merge", $array);

var_dump($values);
?>

/* output:
array(4) {
  [0]=>
  string(3) "foo"
  [1]=>
  string(3) "bar"
  [2]=>
  string(3) "bat"
  [3]=>
  string(3) "rat"
}
*/

The neat feature is that $array could have any number of arrays inside it.
gord at fig dot org
06-May-2003 06:30
If you need to call object and class methods in PHP < 4.0.4, the following code ought to do the trick:

<?php
if (!function_exists('call_user_func_array')) {
   function
call_user_func_array($func, $args)
   {
      
$argString = '';
      
$comma = '';
       for (
$i = 0; $i < count($args); $i ++) {
          
$argString .= $comma . "\$args[$i]";
          
$comma = ', ';
       }

       if (
is_array($func)) {
          
$obj =& $func[0];
          
$meth = $func[1];
           if (
is_string($func[0])) {
               eval(
"\$retval = $obj::\$meth($argString);");
           } else {
               eval(
"\$retval = \$obj->\$meth($argString);");
           }
       } else {
           eval(
"\$retval = \$func($argString);");
       }
       return
$retval;
   }
}
?>
nutbar at innocent dot com
12-Mar-2003 02:29
This function, combined with some others, can allow you to make some really easy & generic function macros (since real macros don't exist in PHP yet).

<?php
function my_printf() {
  
$args = func_get_args();
   return
call_user_func_array('printf', $args);
}
?>

This allows you to use my_printf() just as if it were printf() itself.  Very useful since you don't have to worry about how many arguments any functions take.
NOSPAM dot dont dot remove at thekid dot de
22-Jun-2002 06:19
Unified constructors in PHP4:

<?php
 
class Object {
   function
Object() {
    
$args= func_get_args();
    
call_user_func_array(array(&$this, '__construct'), $args);
   }

   function
__construct($args= NULL) {
    
var_dump($args);
   }
  }

  class
Exception extends Object {
   var
    
$message;
    
   function
__construct($message) {
    
$this->message= $message;
    
parent::__construct();
   }
  }

  class
IOException extends Exception {
  }
 
 
var_dump(
  
error_reporting(),
  
zend_version(),
  
phpversion()
  );
 
 
$c= new IOException('file not found');
 
  echo
'===> Result: '; var_dump($c);
?>

<Function handlingcall_user_func>
 Last updated: Thu, 19 May 2005
Copyright © 2001-2005 The PHP Group
All rights reserved.
This unofficial mirror is operated at: The Server Pages
Last updated: Thu May 19 17:35:34 2005 CDT