2011-08-15 14 views
60
class MyClass { 
    var $lambda; 
    function __construct() { 
    $this->lambda = function() {echo 'hello world';}; 
    // no errors here, so I assume that this is legal 
    } 
} 

$myInstance = new MyClass(); 
$myInstance->lambda(); 
//Fatal error: Call to undefined method MyClass::lambda() 

तो कक्षा चर तक पहुंचने के लिए सही वाक्यविन्यास क्या है?एक क्लास वेरिएबल बंद करने के लिए कैसे कॉल करें?

उत्तर

158

PHP में, विधियों और गुण एक अलग नामस्थान में हैं (आप एक विधि और एक ही नाम के साथ एक संपत्ति हो सकती है), और चाहे आप किसी संपत्ति या विधि तक पहुंच रहे हों, सिंटैक्स पर निर्भर करता है जिसका उपयोग आप ऐसा करने के लिए कर रहे हैं ।

$expr->something() एक विधि कॉल है, इसलिए PHP कक्षाओं की सूची में something खोज करेगा।

$expr->something एक संपत्ति प्राप्त करने वाला है, इसलिए PHP गुणों की सूची में something खोज करेगा।

$myInstance->lambda(); एक विधि कॉल के रूप में पार्स किया गया है, इसलिए पीएचपी अपनी कक्षा में lambda नामक एक विधि की खोज करता है, लेकिन ऐसी कोई विधि (अपरिभाषित विधि त्रुटि के इसलिए कॉल) है।

तो आपको लैम्ब्डा लाने के लिए fetch प्रॉपर्टी वाक्यविन्यास का उपयोग करना होगा, और फिर उसे कॉल करें।

  • पीएचपी 7.0 के बाद से, आप ($obj->lambda)() के साथ ऐसा कर सकते हैं:

    ($obj->lambda)(); 
    

    कोष्ठकों यकीन है कि पीएचपी पार्स करता है कि ($obj->lambda)के रूप में संपत्ति लैम्ब्डा नामित लाने बनाते हैं। फिर, () संपत्ति लाने के परिणाम को कॉल करता है।

  • या आप ->lambda->__invoke() के साथ ऐसा कर सकते हैं:

    $myInstance = new MyClass(); 
    $myInstance->lambda->__invoke(); 
    

    __invokePHP's magic methods से एक है। जब कोई ऑब्जेक्ट इस विधि को लागू करता है, तो यह अनावश्यक हो जाता है: इसे $var() सिंटैक्स का उपयोग करके बुलाया जा सकता है। बेनामी फ़ंक्शंस Closure के उदाहरण हैं, जो __invoke लागू करता है।

  • या यह एक स्थानीय चर के लिए असाइन:

    $lambda = $myInstance->lambda; 
    $lambda(); 
    
  • या call_user_func का उपयोग कर इसे कहते:

    call_user_func($myInstance->lambda); 
    

    call_user_func अनाम प्रक्रियाएं सहित किसी भी callable कॉल कर सकते हैं,।

  • वैकल्पिक रूप से, अगर यह अपने कोड में एक आम पैटर्न है, आप सेटअप एक __call विधि अपने लैम्ब्डा पर कॉल अग्रेषित करने कर सकते हैं:

    class MyClass 
    { 
        private $lambda; 
    
        public function __construct() 
        { 
         $this->lambda = function() { 
          echo "Hello world!\n"; 
         }; 
        } 
    
        public function __call($name, $args) 
        { 
         return call_user_func_array($this->$name, $args); 
        } 
    } 
    

    अब इस काम करता है:

    $myInstance = new MyClass(); 
    $myInstance->lambda(); 
    

    पीएचपी के बाद से 5।4 तुम भी ऐसा कर सकते हैं एक विशेषता में:

    trait LambdasAsMethods 
    { 
        public function __call($name, $args) 
        { 
         return call_user_func_array($this->$name, $args); 
        } 
    } 
    
    class MyClass 
    { 
        use LambdasAsMethods; 
    
        private $lambda; 
    
        public function __construct() 
        { 
         $this->lambda = function() { 
          echo "Hello World!\n"; 
         }; 
        } 
    } 
    
    $myInstance = new MyClass(); 
    $myInstance->lambda(); 
    
+9

सुंदर सही व्याख्या) – Rudie

+0

अच्छा है, हालांकि यह '__invoke /()' 'बनाम call_user_func' नोट देखने के लिए अच्छा होगा है। –

+1

बहुत अच्छी व्याख्या! उदाहरणों में बहुत समृद्ध। – Ricardo

2

आप भी अपनी कक्षा में कुछ परिवर्तन के बिना अपने लैम्ब्डा समारोह कॉल कर सकते हैं, ReflectionFunction का उपयोग कर।

$myInstance = new MyClass(); 
$lambda = new ReflectionFunction($myInstance->lambda); 
$lambda->invoke(); 

या आप, = तो तर्क पारित करने के लिए

$args = array('arg'=>'value'); 
$lambda->invokeArgs($args); 
+0

यह सबसे छोटा नहीं है, न ही इसके बारे में जाने का सबसे प्रभावी तरीका है। – amphetamachine

संबंधित मुद्दे