PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

call_user_func> <Fonctions sur la gestion des fonctions
Last updated: Fri, 20 Jun 2008

view this page in

call_user_func_array

(PHP 4 >= 4.0.4, PHP 5)

call_user_func_array — Appelle une fonction utilisateur avec les paramètres rassemblés en tableau

Description

mixed call_user_func_array ( callback $function , array $param_arr )

Appelle la fonction utilisateur function avec les paramètres param_arr , rassemblés dans un tableau.

Liste de paramètres

function

La fonction à appeler.

param_arr

Les paramètres à passer à la fonction, sous la forme d'un tableau indexé.

Valeurs de retour

Retourne le résultat de la fonction, ou FALSE si une erreur survient.

Exemples

Exemple #1 Exemple avec call_user_func_array()

<?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));
?>

Exemple #2 Exemple avec call_user_func_array() en utilisant un espace de nom

<?php

namespace Foobar
;

class 
Foo {
    static public function 
test($name) {
        print 
"Hello {$name}!\n";
    }
}

// Depuis PHP 5.3.0
call_user_func_array(__NAMESPACE__ .'::Foo::test', array('Hannes'));
// Hello Hannes!

// Depuis PHP 5.3.0
call_user_func_array(array(__NAMESPACE__ .'::Foo''test'), array('Philip'));
// Hello Philip!

?>

Notes

Note: Les variables référencées dans le paramètre param_arr sont passées à la fonction par référence, les autres sont passées par leur valeur. En d'autres termes, cela ne dépend pas de la signature de la fonction suivant que le paramètre est passé par valeur ou par référence.

Voir aussi



call_user_func> <Fonctions sur la gestion des fonctions
Last updated: Fri, 20 Jun 2008
 
add a note add a note User Contributed Notes
call_user_func_array
thiago dot henrique dot mata at gmail dot com
22-Jul-2008 02:17
<?php
Class Delegate
{
    private
$arrInstances = array();
   
    protected function
addObject( $oElement )
    {
       
// add one element on the end of the stack  //
       
$this->arrInstances[] = $oElement;
    }   
   
    public function
__call( $strMethod, $arrParams )
    {
       
// for each element in instance //
       
foreach( $this->arrInstances as $oElement )
        {
           
// get the class of the element //
           
$strClass = get_class( $oElement );
           
// get all methods of the class  //
           
$arrMethods = get_class_methods( $strClass );
           
// case the method exists into this class  //
           
if( in_array( $strMethod , $arrMethods ) )
            {
               
// prepare caller //
               
$arrCaller = Array( $strClass , $strMethod );
               
// return the result of the method into the object  //
               
return call_user_func_array( $arrCaller, $arrParams );
            }
        }
       
// any object has the method //
        // throw a exception //
       
throw new Exception( " Method " . $strMethod . " not exist in this class " . get_class( $this ) . "." );
    }
}

class
Log
{
    public function
sayHi()
    {
        print
"hi!" . "<br/>\n";
    }
   
    public function
sayMyName()
    {
        print
"log" . "<br/>\n";
    }
}

class
Other
{
    public function
sayHello()
    {
        print
"hello there!" . "<br/>\n";
    }
   
    public function
sayMyName()
    {
        print
"other" . "<br/>\n";
    }
}

class
Example extends Delegate
{
    public function
__construct()
    {
       
$this->addObject( new Log() );
       
$this->addObject( new Other() );
    }
}

$oExample = new Example();
$oExample->sayHi();
$oExample->sayHello();
$oExample->sayMyName();

/*
    hi!<br/>
    hello there!<br/>
    log<br/>
*/
?>
dnhuff at acm.org
07-Jun-2008 11:57
It appears that when PHP executes something like:

$a = array(1,2,3);
$b =& $a[1];

both $b and $a[1] are converted into references to a common value -- makes sense until you transfer that to a call_user_func:

call_user_func_array('foo', $a);

suddenly, inside foo, the second parameter is passed by reference!

And you can't call this wrong, only another subtly of references.

Note it appears that ksort($a) will remove the reference as well as put the elements in key order so you (probably) get what you expect. (see below on the use of a foreach ($a as &v).)
dnhuff at acm.org
07-Jun-2008 11:38
the order of argument correspondence from the array to the function formal parameters is by 'natural order' of the array and not explicit numerical key order.

So: $a[0] = 'arg 1'; $a[2] = 'arg 2'; $a[1] = 'arg 3';
    call_user_func_array('foo', $a);

delivers the args to foo in the order the keys were inserted! as in...
    foo($a[0], $a[2], $a[1]);

if you wanted something else, ksort the array first.
aeolianmeson at 8n54tvv dot blitzeclipse dot com
27-May-2008 08:48
There's a possibility that call_user_func_array(), call_user_func(), and Exception::getTrace() will cause a trace entry to not have the 'file' or 'line' elements.

Dustin Oprea
richard_harrison at rjharrison dot org
11-Apr-2007 02:31
If you are thinking of using call_user_func_array to instantiate an object (see comments below using Reflection) then since v5.1.3 you can use the Reflection::newInstanceArgs() method.

<?php

// arguments you wish to pass to constructor of new object
$args = array('a', 'b');

// class name of new object
$className = 'myCommand';

// make a reflection object
$reflectionObj = new ReflectionClass($className);

// use Reflection to create a new instance, using the $args
$command = $reflectionObj->newInstanceArgs($args);

// this is the same as: new myCommand('a', 'b');
?>
levi at alliancesoftware dot com dot au
08-Feb-2007 02:50
Regarding the comments below about calling parent constructors:

PHP5 with E_STRICT no longer allows calls as below:

<?php
// Causes an error with E_STRICT
call_user_func_array(array('parent', '__construct'), $args);
?>

It gives an error because you are trying to call a nonstatic function as if it was static. The correct syntax is

<?php
// Works fine
call_user_func_array(array($this, 'parent::__construct'), $args);
?>
15-May-2006 02:43
For those wishing to implement call-by-name functionality in PHP, such as implemented e.g. in DB apis, here's a quick-n-dirty version for PHP 5 and up
<?php
/**
 * Call a user function using named instead of positional parameters.
 * If some of the named parameters are not present in the original function, they
 * will be silently discarded.
 * Does no special processing for call-by-ref functions...
 * @param string $function name of function to be called
 * @param array $params array containing parameters to be passed to the function using their name (ie array key)
 */
function call_user_func_named($function, $params)
{
   
// make sure we do not throw exception if function not found: raise error instead...
    // (oh boy, we do like php 4 better than 5, don't we...)
   
if (!function_exists($function))
    {
       
trigger_error('call to unexisting function '.$function, E_USER_ERROR);
        return
NULL;
    }
   
$reflect = new ReflectionFunction($function);
   
$real_params = array();
    foreach (
$reflect->getParameters() as $i => $param)
    {
       
$pname = $param->getName();
        if (
$param->isPassedByReference())
        {
           
/// @todo shall we raise some warning?
       
}
        if (
array_key_exists($pname, $params))
        {
           
$real_params[] = $params[$pname];
        }
        else if (
$param->isDefaultValueAvailable()) {
           
$real_params[] = $param->getDefaultValue();
        }
        else
        {
           
// missing required parameter: mark an error and exit
            //return new Exception('call to '.$function.' missing parameter nr. '.$i+1);
           
trigger_error(sprintf('call to %s missing parameter nr. %d', $function, $i+1), E_USER_ERROR);
            return
NULL;
        }
    }
    return
call_user_func_array($function, $real_params);
}
?>
eugene at artprime dot ru
23-Dec-2005 02:59
<?php
 
return call_user_func_array(
    array(new
ReflectionClass($className), 'newInstance'),
   
$functionParameters
 
);
?>

Look here: http://www.zend.com/zend/week/week182.php#Heading1
crocodile2u at yandex dot ru
20-Dec-2005 05:06
Here is another version of createObjArray() function written here earlier by taylor.

Believing that using 'eval()' is at least "dirty", I came to the following solution (with a help of panchous - at phpclub dot ru forums ). This solution utilizes the new Reflection API.

<?php
function & createObjArray($type, $args = array()) {
   
$reflection = new ReflectionClass($type);
   
$output     = call_user_func_array(array(&$reflection, 'newInstance'), $args);
    return
$output;
}
?>
Egor
15-Nov-2005 09:35
Note that, despite the name, this does work on builtin functions (and object methods with the array(&$obj, $method) syntax), not just user-defined functions and methods.
rrant (at) gmail (dot) com
10-Nov-2005 03:50
Just an extra for the post of amer at o2 dot pl:

If you need to call the PARENT method:
call_user_func_array(array('parent', 'method'), $args);

With that, if you need to call a constructor and/or add some extra code to the instantiation process:

<?php
function __construct() {
   
// Get the arguments
   
$args = func_get_args();
   
// Initialize parent with arguments
   
call_user_func_array(array('parent', '__construct'), $args);
   
// ... Your Code Here ...
}
?>

Note that your constructor pass all the arguments to the parent constructor and it doesn't matter how many arguments you pass.

This is pretty useful for constructors with a variable number of arguments.
taylor
02-Jun-2005 05:51
I came up with a better solution to the problem that I solve below with createObjArray that maintains parameter type:

<?php

function createObjArray($type,$args=array()) {
    
$paramstr = '';
     for (
$i = 0; $i < count($args); $i++) {
          
$paramstr .= '$args['.$i.'],';
     }
    
$paramstr = rtrim($paramstr,',');

     return eval(
"return new $type($paramstr);");
}

?>

Would be good to add error checking, but it works.
taylor
07-May-2005 03: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 02: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 05: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 05: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 03: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 09: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".
adamh at densi dot com
31-Jul-2003 11: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 04: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 12: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 04: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);
?>

call_user_func> <Fonctions sur la gestion des fonctions
Last updated: Fri, 20 Jun 2008
 
 
show source | credits | stats | sitemap | contact | advertising | mirror sites