the art of PHP callbackThe 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.