Mixed »
« Les ressources
- Manuel PHP
- Référence du langage
- Les types
Les fonctions de rappel peuvent être identifiées via le type callable.
Certaines fonctions, comme call_user_func() ou usort(), acceptent comme paramètre des fonctions de rappel définies par l'utilisateur. Les fonctions de rappel peuvent être de simples fonctions, mais aussi des méthodes d'objets, y compris des méthodes statiques de classe.
Passage d'une fonction de rappel
Une fonction PHP est passée par son nom, sous forme de chaîne de caractères. Toute fonction interne ou définie par l'utilisateur peut être utilisée, sauf les constructions de langage comme : array(), echo, empty(), eval(), exit(), isset(), list(), print, ou unset().
Une méthode d'un objet instancié est passée comme un tableau contenant un objet à l'index 0, et le nom de la méthode à l'index 1. Accéder aux méthodes protégées et privées à l'intérieur d'une classe est autorisé.
Les méthodes statiques de classe peuvent aussi être passées sans instancier d'objet de cette classe soit, en passant le nom de la classe au lieu d'un objet à l'index 0, ou en passant 'NomDeLaClasse::NomDeLaMethode'
.
En dehors des fonctions définies normalement par l'utilisateur, les fonctions anonymes et les fonctions fléchées peuvent aussi être utilisées comme paramètre de type callback.
Note:
À partir de PHP 8.1.0, les fonctions anonymes peuvent aussi être créées en utilisant la syntaxe callable de première classe.
Généralement, tout objet implémentant __invoke() peut aussi être passé au paramètre callback.
Exemple #1 Exemples de fonctions de rappel
class <?php // Un exemple de fonction de rappel
function my_callback_function() {
echo 'hello world!';
}// Un exemple de méthode de rappel
class MyClass {
static function myCallbackMethod() {
echo 'Hello World!';
}
}// Type 1 : Fonction de rappel simple
call_user_func('my_callback_function'); // Type 2 : Appel d'une méthode statique de classe
call_user_func(array('MyClass', 'myCallbackMethod')); // Type 3 : Appel d'une méthode objet
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));// Type 4 : Appel d'une méthode statique de classe
call_user_func('MyClass::myCallbackMethod');// Type 5 : Appel à une méthode statique de classe relative
class A {
public static function who() {
echo "A\n";
}
}
public static function who() {
echo "B\n";
}
}call_user_func(array('B', 'parent::who')); // A, obsoléte à partir de PHP 8.2.0
// Type 6 : Les objets implémentent __invoke peuvent être utilisés comme callables
class C {
public function __invoke($name) {
echo 'Hello ', $name, "\n";
}
}$c = new C();
call_user_func($c, 'PHP!');
?>
Exemple #2 Exemple d'une fonction de rappel utilisant une Closure
print <?php
// Notre closure
$double = function($a) {
return $a * 2;
};// Ceci est notre intervalle de nombres
$numbers = range(1, 5);// Utilisation de la closure comme fonction de rappel.
// Ici, pour doubler la taille de chaque élément de notre intervalle
$new_numbers = array_map($double, $numbers);
?>
L'exemple ci-dessus va afficher :
2 4 6 8 10
Note:
Notez que les fonctions de rappel enregistrées avec des fonctions comme call_user_func() et call_user_func_array() ne seront pas appelées si une exception n'est pas interceptée alors qu'elle a été lancée dans une précédente fonction de rappel.
Improve This Page
+add a note
User Contributed Notes 12 notes
up
down
273
andrewbessa at gmail dot com ¶
11 years ago
<?php public public function public function }You can also use the $this variable to specify a callback:
class MyClass {
{
call_user_func(array($this, 'myCallbackMethod'));
}
{
echo $this->property;
}
up
down
192
Riikka K ¶
9 years ago
- Using the name of a function as string has worked since at least 4.3.0 Note, however, that the following are not supported when calling callbacks as variable functions, even though they are supported by call_user_func(): - Calling static class methods via strings such as 'foo::doStuff' All of these cases are correctly recognized as callbacks by the 'callable' type hint, however. Thus, the following code will produce an error "Fatal error: Call to undefined function foo::doStuff() in /tmp/code.php on line 4": <?php static function A note on differences when calling callbacks as "variable functions" without the use of call_user_func() (e.g. "<?php $callback = 'printf'; $callback('Hello World!') ?>"):
- Calling anonymous functions and invokable objects has worked since 5.3.0
- Using the array structure [$object, 'method'] has worked since 5.4.0
- Calling parent method using the [$object, 'parent::method'] array structure
class foo {
static function callIt(callable $callback) {
$callback();
}
echo "Hello World!";
}
}foo::callIt('foo::doStuff');
?>
The code would work fine, if we replaced the '$callback()' with 'call_user_func($callback)' or if we used the array ['foo', 'doStuff'] as the callback instead.
up
down
193
computrius at gmail dot com ¶
10 years ago
<?phpclass mc { private function public function When specifying a call back in array notation (ie. array($this, "myfunc") ) the method can be private if called from inside the class, but if you call it from outside you'll get a warning:
public function go(array $arr) {
array_walk($arr, array($this, "walkIt"));
}
echo $val . "<br />";
}
return array($this, 'walkIt');
}
}$data = array(1,2,3,4);$m = new mc;
$m->go($data); // validarray_walk($data, $m->export()); // will generate warning?>
Output:
1<br />2<br />3<br />4<br />
Warning: array_walk() expects parameter 2 to be a valid callback, cannot access private method mc::walkIt() in /in/tfh7f on line 22
up
down
208
steve at mrclay dot org ¶
11 years ago
Performance note: The callable type hint, like is_callable(), will trigger an autoload of the class if the value looks like a static method callback.
up
down
191
edanschwartz at gmail dot com ¶
9 years ago
<?php public static function class For this reason you should always use the full class name:You can use 'self::methodName' as a callable, but this is dangerous. Consider this example:
class Foo {
public static function doAwesomeThings() {
FunctionCaller::callIt('self::someAwesomeMethod');
}
// fantastic code goes here.
}
}
public static function callIt(callable $func) {
call_user_func($func);
}
}Foo::doAwesomeThings();
?>
This results in an error:
Warning: class 'FunctionCaller' does not have a method 'someAwesomeMethod'.
<?php
FunctionCaller::callIt('Foo::someAwesomeMethod');
?>
I believe this is because there is no way for FunctionCaller to know that the string 'self' at one point referred to to `Foo`.
up
down
175
metamarkers at gmail dot com ¶
11 years ago
you can pass an object as a callable if its class defines the __invoke() magic method..
up
down
114
mariano dot REMOVE dot perez dot rodriguez at gmail dot com ¶
8 years ago
<?php/**I needed a function that would determine the type of callable being passed, and, eventually,
normalized it to some extent. Here's what I came up with:
* The callable types and normalizations are given in the table below:
*
* Callable | Normalization | Type
* ---------------------------------+---------------------------------+--------------
* function (...) use (...) {...} | function (...) use (...) {...} | 'closure'
* $object | $object | 'invocable'
* "function" | "function" | 'function'
* "class::method" | ["class", "method"] | 'static'
* ["class", "parent::method"] | ["parent of class", "method"] | 'static'
* ["class", "self::method"] | ["class", "method"] | 'static'
* ["class", "method"] | ["class", "method"] | 'static'
* [$object, "parent::method"] | [$object, "parent::method"] | 'object'
* [$object, "self::method"] | [$object, "method"] | 'object'
* [$object, "method"] | [$object, "method"] | 'object'
* ---------------------------------+---------------------------------+--------------
* other callable | idem | 'unknown'
* ---------------------------------+---------------------------------+--------------
* not a callable | null | false
*
* If the "strict" parameter is set to true, additional checks are
* performed, in particular:
* - when a callable string of the form "class::method" or a callable array
* of the form ["class", "method"] is given, the method must be a static one,
* - when a callable array of the form [$object, "method"] is given, the
* method must be a non-static one.
*
*/
function callableType($callable, $strict = true, callable& $norm = null) {
if (!is_callable($callable)) {
switch (true) {
case is_object($callable):
$norm = $callable;
return 'Closure' === get_class($callable) ? 'closure' : 'invocable';
case is_string($callable):
$m = null;
if (preg_match('~^(?<class>[a-z_][a-z0-9_]*)::(?<method>[a-z_][a-z0-9_]*)$~i', $callable, $m)) {
list($left, $right) = [$m['class'], $m['method']];
if (!$strict || (new \ReflectionMethod($left, $right))->isStatic()) {
$norm = [$left, $right];
return 'static';
}
} else {
$norm = $callable;
return 'function';
}
break;
case is_array($callable):
$m = null;
if (preg_match('~^(:?(?<reference>self|parent)::)?(?<method>[a-z_][a-z0-9_]*)$~i', $callable[1], $m)) {
if (is_string($callable[0])) {
if ('parent' === strtolower($m['reference'])) {
list($left, $right) = [get_parent_class($callable[0]), $m['method']];
} else {
list($left, $right) = [$callable[0], $m['method']];
}
if (!$strict || (new \ReflectionMethod($left, $right))->isStatic()) {
$norm = [$left, $right];
return 'static';
}
} else {
if ('self' === strtolower($m['reference'])) {
list($left, $right) = [$callable[0], $m['method']];
} else {
list($left, $right) = $callable;
}
if (!$strict || !(new \ReflectionMethod($left, $right))->isStatic()) {
$norm = [$left, $right];
return 'object';
}
}
}
break;
}
$norm = $callable;
return 'unknown';
}
$norm = null;
return false;
}?>
Hope someone else finds it useful.
up
down
10
InvisibleSmiley ¶
3 years ago
<?php function If you pass a callable method to a function with a callable type declaration, the error message is misleading:
class X {
protected function foo(): void {}
}
$c = [$x, 'foo'];
bar($c);
?>
Error message will be something like "Argument #1 ($c) must be of type callable, array given" while the actual problem here is only the visibility of method "foo". All you need to do is changing it to public (or use a different approach, e.g. with a Closure).
up
down
9
gulaschsuppe2 at gmail dot com ¶
4 years ago
<?php// Call function via function name: // A function can also be called if its name is assigned to a variable: // Static class method: // Non static class method: public function public function (new I tried many possible ways of calling functions by function name directly and assigned to a variable on 3v4l. Not mentioned yet, it is possible to use an array as a caller, at least since PHP 7.1.25. The following script contains all the information I gained:
// Basics:
// A function can also be called by using its string name:
function callbackFunc() {
echo 'Hello World';
}'callbackFunc'(); // Hello World
echo 'Hello World';
}$funcName = 'callbackFunc';
$funcName(); // Hello World
// It is also possible to call a public static class method via 'ClassName::functioName' notation:
public static function callbackMethod() {
echo "Hello World\n";
}
}
'A::callbackMethod'(); // Hello World$funcName = 'A::callbackMethod';
$funcName(); // Hello World
// It is also possible to call non static class methods by creating an array which first element is the object the method should be called on and the second element is the non static method to be called. The array can directly be used as a caller:
private $prop = "Hello World\n";
echo $this->prop;
}
}$a = new A;
[$a, 'callbackMethod']();
$funcCallArr = [$a, 'callbackMethod'];
$funcCallArr();// Of course this also works inside the class with '$this':
class A {
private function privCallback() {
echo 'Private';
}
[$this, $funcName]();
}
}
up
down
24
bradyn at NOSPAM dot bradynpoulsen dot com ¶
8 years ago
<?phpnamespace MyNamespace; function When trying to make a callable from a function name located in a namespace, you MUST give the fully qualified function name (regardless of the current namespace or use statements).
{
// do something...
}$values = [1, 2, 3];array_map('doSomethingFancy', $values);
// array_map() expects parameter 1 to be a valid callback, function 'doSomethingFancy' not found or invalid function namearray_map('MyNamespace\doSomethingFancy', $values);
// => [..., ..., ...]
up
down
4
pawel dot tadeusz dot niedzielski at gmail dot com ¶
8 years ago
You can use ::class property to always indicate the class you're in when using static methods: <?php public static function class @edanschwartz at gmail dot com
class Foo {
public static function doAwesomeThings() {
FunctionCaller::callIt(self::class . '::someAwesomeMethod');
}
// fantastic code goes here.
}
}
public static function callIt(callable $func) {
call_user_func($func);
}
}Foo::doAwesomeThings();
?>
up
down
2
chris dot rutledge at gmail dot com ¶
5 years ago
"A method of an instantiated object is passed as an array containing an object at index 0 and the method name at index 1. Accessing protected and private methods from within a class is allowed." I decided to do some testing to see if I could access private methods using the call_user_func methods. Thankfully not, but for completeness here is my test which also covers using static and object contexts <?php public static public function public function private function public function public function Having read this line in the manual above,
class foo {
self::$isInstance = true;
}
var_dump(self::$isInstance);
echo __METHOD__;
}
var_dump(self::$isInstance);
echo __METHOD__;
}
$this->baz();
}
self::baz();
}
}call_user_func(['foo','bar']); //fase, foo:barcall_user_func(['foo','baz']); //warning, cannot access private methodcall_user_func(['foo','quux']); //false, foo::bazcall_user_func(['foo','qux']); //fatal, Using $this when not in object context $foo = new foo;call_user_func([$foo,'bar']); //true, foo::bar
call_user_func([$foo,'baz']); //warning, cannot access private method
call_user_func([$foo,'qux']); //true, foo::bazcall_user_func(['foo','bar']); //true, foo::bar (static call, yet $isInstance is true)?>
+add a note