Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP - Callable method not as array

Tags:

php

callable

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?

like image 637
marcosh Avatar asked Sep 08 '15 13:09

marcosh


People also ask

What is callable data type in PHP?

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.

Are PHP functions callable?

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.

What is PHP callback function?

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.

How do you check if a function has been called in PHP?

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.


2 Answers

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.

like image 134
geek-merlin Avatar answered Oct 01 '22 19:10

geek-merlin


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:

  • an array [class, method] for a static method
  • an array [object, method] for an instance method
  • a string for a function
  • a Closure instance
  • an object that implements the magic method __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.

like image 31
Fabian Schmengler Avatar answered Oct 01 '22 20:10

Fabian Schmengler