그들 사이의 가장 큰 차이점은이 있다는 것입니다 closure
A는 클래스 와 유형 .callable
이 callable
유형은 호출 할 수있는 모든 항목을 허용합니다 .
var_dump(
is_callable('functionName'),
is_callable([$myClass, 'methodName']),
is_callable(function(){})
);
어디가 closure
됩니다 만 익명 함수를 받아들입니다. PHP 버전 7.1에서는 다음과 같이 함수를 클로저로 변환 할 수 있습니다
Closure::fromCallable('functionName')
.
예:
namespace foo{
class bar{
private $val = 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->myCallable(function(){});
$fb->myCallable($cb);
$fb->myCallable('func');
$fb->myClosure(function(){});
$fb->myClosure($cb);
$fb->myClosure(\Closure::fromCallable('func'));
$fb->myClosure('func'); # TypeError
}
그렇다면 왜 closure
오버를 사용 callable
합니까?
a closure
는 몇 가지 추가 메소드가있는 오브젝트 이므로 call()
, bind()
및 bindto()
. 클래스 외부에서 선언 된 함수를 사용하여 마치 클래스 내부에있는 것처럼 실행할 수 있습니다.
$inject = function($i){return $this->val * $i;};
$cb1 = Closure::bind($inject, $fb);
$cb2 = $inject->bindTo($fb);
echo $cb1->call($fb, 2); // 20
echo $cb2(3); // 30
치명적인 오류가 발생할 수 있으므로 일반 함수에서 메소드를 호출하고 싶지 않습니다. 따라서이를 피하려면 다음과 같이 작성해야합니다.
if($cb instanceof \Closure){}
이 점검을 할 때마다 의미가 없습니다. 따라서 해당 메소드를 사용하려면 인수가입니다 closure
. 그렇지 않으면 normal을 사용하십시오 callback
. 이 방법; 코드 대신 함수 호출에서 오류가 발생하여 훨씬 쉽게 진단 할 수 있습니다.
보조 노트에 :closure
클래스는 그것으로 확장 할 수 없습니다 마지막 .
["Foo", "bar"]
forFoo::bar
또는[$foo, "bar"]
for 와 같은 배열을 전달하여 callable과 함께 클래스 메서드를 사용할 수도 있습니다$foo->bar
.