Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP force instance of Closure, sort of

To quote PHP:

Anonymous functions are currently implemented using the Closure class. This is an implementation detail and should not be relied upon.

Now, that said, the following checks are deemed unreliable:

function myFunction(Closure $callback){}

if(!($callback instanceof Closure)){}

Which brings us to using is_callable(). This is fine, however if one requires a true "closure", (as an argument, or what-such) then is_callable() isn't strict enough. The following of course dumps bool(true) for each:

function myFunction(){}

class MyClass{
    public function __invoke(){}
}

var_dump(is_callable('myFunction'));
var_dump(is_callable(new MyClass));

How, without relying on the Closure class (given is is in fact unreliable) can one strictly identify a "closure"?


Update

It has occurred to me I was falling in the direction of bad design. However, despite this question being answered, I think it would be appreciated if anyone could suggest answers to the posed question, if not purely for the academic element of it.

Update (again)

Since the release of PHP 5.4 (awhile ago now) the Closure type is no longer an "implementation detail", and can be relied on. function f(Closure $g) { } is all good.

like image 211
Dan Lugg Avatar asked Dec 22 '22 11:12

Dan Lugg


2 Answers

It seems that PHP developers changed their mind about Closure class being an implementation detail:

Anonymous functions, implemented in PHP 5.3, yield objects of this type. This fact used to be considered an implementation detail, but it can now be relied upon.

See http://php.net/manual/en/class.closure.php

Therefore you should consider now your checks are reliable:

function myFunction(Closure $callback){}

if(!($callback instanceof Closure)){}
like image 73
Radu Gasler Avatar answered Dec 24 '22 01:12

Radu Gasler


The only time you should be typing arguments is when there is something about that particular class which you need. Even then, you are better off with use of an interface. That is just good OOP design.

I cannot fathom the existence of a situation where there would be a benefit to forcing something to be a Closure. The only thing which should matter, in that case, is whether or not the parameter "is_callable". Even if it were possible to accomplish your goal, I would argue that it is unexpected functionality of a framework and therefore anti-pattern.

like image 21
cwallenpoole Avatar answered Dec 24 '22 01:12

cwallenpoole