php - Type hinting – Difference between `Closure` and `Callable`


I noticed that I can use either ofClosure orCallable as type hint if we expected some callback function to run. For example:

function callFunc1(Closure $closure) {

function callFunc2(Callable $callback) {

$function = function() {
    echo 'Hello, World!';

callFunc1($function); // Hello, World!
callFunc2($function); // Hello, World!


What's the difference here? In other words when to useClosure and when to useCallable or do they serve the same purpose?




The main difference between them is that a is a class and a type.

Thecallable type accepts anything that can be called:

  is_callable([$myClass, 'methodName']),
); // all true

Where aclosure will only accept an anonymous function. Note that in PHP version 7.1 you can convert functions to a closure like so: .


namespace foo{
  class bar{
    private $baz = 10;

    function myCallable(callable $cb){$cb()}
    function myClosure(\Closure $cb){$cb()} // type hint must refer to global namespace

  function func(){}
  $cb = function(){};
  $fb = new bar;


  $fb->myClosure('func'); # TypeError

So why use aclosure overcallable?

Strictness because aclosure is an object that has some additional methods: , and . They allow you to use a function declared outside of a class and execute it as if it was inside a class:

$inject = function($i){return $this->baz * $i;};
$cb1 = \Closure::bind($inject, $fb);
$cb2 = $inject->bindTo($fb);

echo $cb1->call($fb, 2); // 20
echo $cb2(3);            // 30

You would not like to call methods on a normal function as that will raise fatal errors. So in order to circumvent that you would have to write something like:

if($cb instanceof \Closure){}

To do this check every time is pointless. So if you want to use those methods state that the argument is aclosure. Otherwise just use a normalcallback. This way; An error is raised on function call instead of your code causing it making it much easier to diagnose.

On a side note: Theclosure class cannot be extended as its final.




It's worth mentioning that this won't work for PHP versions 5.3.21 to 5.3.29.

In any of those versions you will get an output like:

Hello, World! Catchable fatal error: Argument 1 passed to callFunc2() must be an instance of > Callable, instance of Closure given, called in /in/kqeYD on line 16 and defined in /in/kqeYD on line 7

Process exited with code 255.

One can try that out using

Best regards,

People are also looking for solutions to the problem: Laravel PHP: Do not display 'blank' checkbox data in view


Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.