Callbacks

Callbacks can be denoted by callable type hint as of PHP 5.4. This documentation used callback type information for the same purpose.

Some functions like call_user_func() or usort() accept user-defined callback functions as a parameter. Callback functions can not only be simple functions, but also object methods, including static class methods.

Passing

A PHP function is passed by its name as a string. Any built-in or user-defined function can be used, except language constructs such as: array(), echo, empty(), eval(), exit(), isset(), list(), print or unset().

A method of an instantiated object is passed as an array containing an object at index 0 and the method name at index 1.

Static class methods can also be passed without instantiating an object of that class by passing the class name instead of an object at index 0. As of PHP 5.2.3, it is also possible to pass 'ClassName::methodName'.

Apart from common user-defined function, anonymous functions can also be passed to a callback parameter.

Пример #1 Callback function examples

<?php 

// An example callback function
function my_callback_function() {
    echo 
'hello world!';
}

// An example callback method
class MyClass {
    static function 
myCallbackMethod() {
        echo 
'Hello World!';
    }
}

// Type 1: Simple callback
call_user_func('my_callback_function'); 

// Type 2: Static class method call
call_user_func(array('MyClass''myCallbackMethod')); 

// Type 3: Object method call
$obj = new MyClass();
call_user_func(array($obj'myCallbackMethod'));

// Type 4: Static class method call (As of PHP 5.2.3)
call_user_func('MyClass::myCallbackMethod');

// Type 5: Relative static class method call (As of PHP 5.3.0)
class {
    public static function 
who() {
        echo 
"A\n";
    }
}

class 
extends {
    public static function 
who() {
        echo 
"B\n";
    }
}

call_user_func(array('B''parent::who')); // A
?>

Пример #2 Callback example using a Closure

<?php
// Our closure
$double = function($a) {
    return 
$a 2;
};

// This is our range of numbers
$numbers range(15);

// Use the closure as a callback here to 
// double the size of each element in our 
// range
$new_numbers array_map($double$numbers);

print 
implode(' '$new_numbers);
?>

Результат выполнения данного примера:

2 4 6 8 10

Замечание: In PHP 4, it was necessary to use a reference to create a callback that points to the actual object, and not a copy of it. For more details, see References Explained.

Замечание:

Callback-функции, зарегистрированные такими функциями как call_user_func() и call_user_func_array(), не будут вызваны при наличии не пойманного исключения, брошенного в предыдущей callback-функции.

Коментарии

You can also use the $this variable to specify a callback:

<?php
class MyClass {

    public 
$property 'Hello World!';

    public function 
MyMethod()
    {
       
call_user_func(array($this'myCallbackMethod'));
    }

    public function 
MyCallbackMethod()
    {
        echo 
$this->property;
    }

}
?>
2012-06-19 06:16:29
http://php5.kiev.ua/manual/ru/language.types.callable.html
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.
2012-09-18 00:00:06
http://php5.kiev.ua/manual/ru/language.types.callable.html
you can pass an object as a callable if its class defines the __invoke() magic method..
2013-06-03 22:34:43
http://php5.kiev.ua/manual/ru/language.types.callable.html
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:

<?php

class mc {
   public function 
go(array $arr) {
       
array_walk($arr, array($this"walkIt"));
   }

   private function 
walkIt($val) {
       echo 
$val "<br />";
   }

    public function 
export() {
        return array(
$this'walkIt');
    }
}

$data = array(1,2,3,4);

$m = new mc;
$m->go($data); // valid

array_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
2013-10-11 19:38:24
http://php5.kiev.ua/manual/ru/language.types.callable.html
Автор:
> As of PHP 5.2.3, it is also possible to pass 'ClassName::methodName'

You can also use 'self::methodName'.  This works in PHP 5.2.12 for me.
2014-04-16 02:40:22
http://php5.kiev.ua/manual/ru/language.types.callable.html
You can use 'self::methodName' as a callable, but this is dangerous. Consider this example:

<?php
class Foo {
    public static function 
doAwesomeThings() {
       
FunctionCaller::callIt('self::someAwesomeMethod');
    }

    public static function 
someAwesomeMethod() {
       
// fantastic code goes here.
   
}
}

class 
FunctionCaller {
    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'.

For this reason you should always use the full class name:
<?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`.
2015-02-02 20:13:48
http://php5.kiev.ua/manual/ru/language.types.callable.html
Автор:
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!'?>"):

- Using the name of a function as string has worked since at least 4.3.0
- Calling anonymous functions and invokable objects has worked since 5.3.0
- Using the array structure [$object, 'method'] has worked since 5.4.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'
- Calling parent method using the [$object, 'parent::method'] array structure

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
class foo {
    static function 
callIt(callable $callback) {
       
$callback();
    }
   
    static function 
doStuff() {
        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.
2015-05-11 16:36:15
http://php5.kiev.ua/manual/ru/language.types.callable.html
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:

<?php

/**
 * 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 truecallable$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.
2015-09-21 22:45:53
http://php5.kiev.ua/manual/ru/language.types.callable.html
@edanschwartz at gmail dot com

You can use ::class property to always indicate the class you're in when using static methods:

<?php
class Foo {
    public static function 
doAwesomeThings() {
       
FunctionCaller::callIt(self::class . '::someAwesomeMethod');
    }

    public static function 
someAwesomeMethod() {
       
// fantastic code goes here.
   
}
}

class 
FunctionCaller {
    public static function 
callIt(callable $func) {
       
call_user_func($func);
    }
}

Foo::doAwesomeThings();
?>
2016-04-12 17:11:07
http://php5.kiev.ua/manual/ru/language.types.callable.html
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).

<?php

namespace MyNamespace
;

function 
doSomethingFancy($arg1)
{
   
// do something...
}

$values = [123];

array_map('doSomethingFancy'$values);
// array_map() expects parameter 1 to be a valid callback, function 'doSomethingFancy' not found or invalid function name

array_map('MyNamespace\doSomethingFancy'$values);
// => [..., ..., ...]
2016-04-14 04:22:40
http://php5.kiev.ua/manual/ru/language.types.callable.html
Another Appearance of Callbacks! Here is one way of them - methods of an instantiated object can be callable and implemented as variable functions without php's default functions that can call user-defined callback functions.

class Test {
    protected $items = array();

    public function __construct() 
    {
        $this->items[] = array($this, 'callBackOne');
        $this->items[] = array($this, 'callBackTwo');
    }

    public function callBackOne()
    {
        echo __METHOD__ . ' has been called as a callback.';
    }

    public function callBackTwo()
    {
        echo __METHOD__ . ' has been called as a callback.';
    }   

    public function getItems()
    {
        return $this->items;
    }
}

$o = new Test();
$itemLists = $o->getItems();

foreach ($itemLists as $itemList) {

        // call each one as a variable function
        echo '<pre>';
        print_r($itemList());
        echo '</pre>';
}

// Outputs the following
// Test::callBackOne has been called as a callback.

// Test::callBackTwo has been called as a callback.
2017-04-18 09:34:14
http://php5.kiev.ua/manual/ru/language.types.callable.html
Автор:
You can use "self::method_name", "static::method_name" and "parent::method_name" in callables:

<?php
class StaticCallable {
    public static function 
foo($values) {
        return 
array_map('self::bar'$values);
    }

    public static function 
bar($value) {
        return 
"{$value}: 42";
    }

    public static function 
baz($values) {
        return 
array_map('static::qux'$values);
    }

    public static function 
qux($value) {
        return 
"{$value}: 123";
    }
}

class 
StaticExtension extends StaticCallable {
    public static function 
bar($value) {
        return 
"{$value}: Marvin the Paranoid Android";
    }

    public static function 
qux($value) {
        return 
"{$value}: Zaphod Beeblebrox";
    }
}

print_r(StaticCallable::foo([123]));
print_r(StaticExtension::foo([123]));

print_r(StaticCallable::baz([123]));
print_r(StaticExtension::baz([123]));
?>

Results:
Array
(
    [0] => 1: 42
    [1] => 2: 42
    [2] => 3: 42
)
Array
(
    [0] => 1: 42
    [1] => 2: 42
    [2] => 3: 42
)
Array
(
    [0] => 1: 123
    [1] => 2: 123
    [2] => 3: 123
)
Array
(
    [0] => 1: Zaphod Beeblebrox
    [1] => 2: Zaphod Beeblebrox
    [2] => 3: Zaphod Beeblebrox
)

"self::" uses the same class as the called method, "static::" uses the same class as the called class, and "parent::" (not shown) uses the parent class, or generates a warning if there is no parent.
2017-09-13 10:26:59
http://php5.kiev.ua/manual/ru/language.types.callable.html

    Поддержать сайт на родительском проекте КГБ