उनके बीच मुख्य अंतर यह है कि closureएक वर्ग और 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?
सख़्ती क्योंकि एक 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। अन्यथा बस एक सामान्य का उपयोग करें callback। इस तरफ; आपके कोड के बजाय फ़ंक्शन कॉल पर एक त्रुटि उत्पन्न होती है, जिससे इसे निदान करना बहुत आसान हो जाता है।
एक तरफ ध्यान दें पर:closure वर्ग अपनी के रूप में नहीं बढ़ाई जा सकती अंतिम ।
["Foo", "bar"]लिएFoo::barया इसके[$foo, "bar"]लिए$foo->bar।