Usually in PHP if you have a method bar
of a class Foo
and you'd like to pass it around as a callable, you use something like
$foo = new Foo();
$callable = [$foo, 'bar'];
The downside of this is that is_array($callable)
evaluates to true
.
Is there another feasible way to pass around a class method as a callable such that is_array($callable)
returns false
?
Definition and Usage The callable keyword is used to force a function argument to be a reference to a function. A callable can be one of the following: An anonymous function. A string containing the name of a function. An array describing a static class method.
The is_callable() function checks whether the contents of a variable can be called as a function or not. This function returns true (1) if the variable is callable, otherwise it returns false/nothing.
A callback function (often referred to as just "callback") is a function which is passed as an argument into another function. Any existing function can be used as a callback function.
is_callable can be used to check if a function exists like so: function foo() { } echo (int)is_callable('foo'); echo (int)is_callable('bar'); The example code above declares a function called foo() and then uses is_callable by passing in the names of functions to check for. 'foo' exists and 'bar' doesn't.
PHP 7.1 finally took a big steep in making callbacks first-class citizens via Closure::fromCallable (RFC).
As described here, you can use it like this:
class MyClass
{
public function getCallback() {
return Closure::fromCallable([$this, 'callback']);
}
public function callback($value) {
echo $value . PHP_EOL;
}
}
$callback = (new MyClass)->getCallback();
$callback('Hello World');
Using it has some benefits:
Better error handling - When using Closure::fromCallable, it shows errors in the right place instead of showing it where we are using the callable. This makes debugging a lot easier.
Wrapping scopes - The above example will work fine even if the callback is a private/protected method of MyClass.
Performance - This can also improve the performance by avoiding the overhead of checking if the given callable is actually a callable.
Functions and methods are not first class citizens in PHP, i.e. they cannot be assigned to variable, do not have a type etc.
callable
isn't actually a type, is_callable
as well as the callable
type hint just checks if something can be used as a function. This can be:
[class, method]
for a static method[object, method]
for an instance methodClosure
instance__invoke()
As you see, all of these values actually have a different type and just happen to be "callable". There is no such thing as a "pure" callable that does not have another type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With