The art of PHP callback
PHP callback are functions that may be called dynamically by PHP. They are used by native functions such as array_map, usort, preg_replace_callback, etc.
Here is a reminder of the various ways to create a callback function in PHP, and use it with the native functions.
String functions
Strings are the simplest way to dynamically call a function. The name of the function in the string is called. If the function is namespaced, you have to include the full namespace.
<?php $callback = 'strtoupper'; print_r(array_map($callback, $function('uppercase string')); ?>
Note that some PHP native functions, such as ‘echo’ or ‘print’ are not really functions, so they can’t be called directly with this approach. You have to put them in a custom function, and then, call this function.
Fatal error: Call to undefined function echo()
Static Methods
Strings may also call a static method : simply add the class name and the `::` operator to call it. Class may be namespaced if needed.
<?php class x { function f($b) { return strtoupper($b); } } $staticMethod = 'x::f'; print_r(array_map($staticMethod, array('a'))); ?>
Note that the method doesn’t need to be static explicitely. If it isn’t really static (aka, it does use `$this`), there will be errors as `$this` is null.
Static Methods (Part 2)
It is possible to do the same call than the previous one with an array. The array must contain two elements : the class name and the method name. The index must be 0 and 1, respectively.
<?php class x { function f($b) { return strtoupper($b); } } $staticMethod2 = array('x', 'f'); print_r(array_map($staticMethod2, array('a'))); ?>
The same restriction applies to the `static` nature of the method.
Also, note that this syntax also allows the use of ‘parent::’ in the function’s name, making it a call to the parent’s class of the first argument.
<?php class xfather { function f($b) { return strtoupper($b); } } class x extends xfather { } $parentMethod = array('x', 'parent::f'); print_r(array_map($parentMethod, array('a'))); ?>
Normal Methods
The first argument may be replaced by a real object, instead of a string representing a class. This way, the object’s method (and not the class) will be called.
<?php class x { function f($b) { return strtoupper($b); } } $x = new x(); $normalMethod = array($x, 'f'); print_r(array_map($normalMethod, array('a'))); ?>
Callable object
A callable object is an object of a class that implements the magic method `\_\_invoke`. This method will be automagically called when the object is used as a callback.
<?php class x { function __invoke($b){ return strtoupper($b); } } $x = new x(); print_r(array_map($x, array('a'))); ?>
Note that `__invoke` may be defined with an arbitrary number of arguments.
Closures
Closures are functions without a name. Instead of providing a string that will reference compiled code, it is an object that may be called.
<?php $lambda = create_function('$a', 'return strtoupper($a);'); var_dump($lambda); // displays string(9) "\000lambda_1", // which is a function's name, though a forbidden print_r(array_map($lambda, array('a'))); ?>
Arrow functions
Arrow functions are closures with a single expression as body. They also bring into their context, all the local variables of the creating context, in a compact syntax. Arrow functions were introduced in
<?php $string = 'An elephpant'; $arrow = fn ($what) => "$string eats $what"; array_map($arrow, ['grass', 'leaves', 'PHP code']; ?>
create_function()
This is the grand-father of function creation. It is deprecated since PHP 7.2, and removed in PHP 8.0. It is highly recommended to *AVOID* using it, as it is a disguised version of `eval`. There are more modern ways to do this, so it is merely here in case you meet it in a legacy code.
It takes a list of arguments, and some PHP as a string, that will be `eval`’ed.
<?php $create_function = create_function('$a', 'echo $a;'); var_dump($create_function); // displays string(9) "\000lambda_1", // which is a function's name, though a forbidden print_r(array_map($create_function, array('a'))); ?>
Various ways to callback
No more than 7 ways to call a function or a method in PHP.
The modern way is definitely the closure. They are used heavily in frameworks to allow users to define a behavior and feed the framework with it. They are also non-polluting, since they don’t need a specific name.