PHP:types提示 – “Closure”和“Callable”之间的区别
我注意到,如果我们期望一些callback函数运行,我可以使用Closure
或Callable
作为types提示。 例如:
function callFunc1(Closure $closure) { $closure(); } function callFunc2(Callable $callback) { $callback(); } $function = function() { echo 'Hello, World!'; }; callFunc1($function); // Hello, World! callFunc2($function); // Hello, World!
题:
这里有什么区别? 换句话说,何时使用Closure
以及何时使用Callable
OR,它们的用途是相同的?
不同的是, Closure
必须是一个匿名函数, callable
也可以是一个正常的函数。
你可以用下面的例子看看/testing这个,你会看到第一个错误:
function callFunc1(Closure $closure) { $closure(); } function callFunc2(Callable $callback) { $callback(); } function xy() { echo 'Hello, World!'; } callFunc1("xy"); // Catchable fatal error: Argument 1 passed to callFunc1() must be an instance of Closure, string given callFunc2("xy"); // Hello, World!
所以,如果你只想键入提示匿名函数使用: Closure
,如果你还想让正常的function使用callable
的types提示。
它们之间的主要区别是closure
是一个类 , callable
是一种types 。 很容易忘记这一点,因为closure
是一个特殊的类,它并不真正作为其他类初始化。
callable
types接受任何可以callable
东西:
-
call_user_func('my_functionName')
-
call_user_func('MyClass::myStaticMethodName')
-
call_user_func([new MyClass, 'myMethodName'])
-
call_user_func(function(){})
closure
只接受后者(上述#4) 。 自PHP 7.1以来。 但是你可以使用Closure::fromCallable('my_functionName')
将任何函数转换为闭Closure::fromCallable('my_functionName')
。
namespace foo{ class bar{ private $val = 10; // this value will be used in later example code. function a(callable $cb){$cb()} function b(\closure $cb){$cb()} // type hint must refer to global namespace } }
使用下面的代码来testing:
function func(){} $cb = function(){}; $fb = new foo\bar; $fb->a(function(){}); $fb->a($cb); $fb->a('func'); $fb->b(function(){}); $fb->b($cb); $fb->b('func'); # TypeError
那么为什么使用callable
的closure
呢? 那么请记住, closure
是一个具有一些附加方法的对象: bind()
, bindto()
和call()
。 它们允许您使用在类之外声明的函数,并像在类中一样执行它。
$cb1 = function($i){return $this->val * $i;}; $cb2 = Closure::bind($cb1, $fb); $cb3 = $cb1->bindTo($fb); $cbi = (function($i){return $this->val * $i;})->bindTo($fb); // inline, same as $cb3. echo $cb1->call($fb, 2); // 20 echo $cb2(3); // 30 echo $cb3(4); // 40
在旁注: closure
类不能作为其最终的扩展。
值得一提的是,这不适用于PHP版本5.3.21至5.3.29。
在这些版本的任何一个,你会得到一个输出:
你好,世界! 可捕获的致命错误:传递给callFunc2()的参数1必须是> Callable的实例,给出的Closure实例,在第16行的/ in / kqeYD中调用,并在第7行的/ in / kqeYD中定义
用代码255退出进程。
可以使用https://3v4l.org/kqeYD#v5321来尝试一下;
最好的祝福,