2009-10-08 10 views
9

मेरे स्थिति सबसे अच्छा कोड का एक सा के साथ वर्णन किया गया है कक्षा, लेकिन मेरे उद्देश्यों के लिए, यह अच्छा होगा अगर __call फ़ंक्शन उन्हें संभाल सकता है। यह सिर्फ चीजों को लॉट नीदर और अधिक प्रबंधनीय बना देगा।पीएचपी का जादू विधि __call

क्या यह PHP में संभव है?

उत्तर

13

__call() केवल तब लागू किया जाता है जब फ़ंक्शन अन्यथा नहीं मिलता है, इसलिए आपका उदाहरण लिखित रूप में संभव नहीं है।

2

यह सीधे नहीं किया जा सकता है, लेकिन यह एक संभावित विकल्प है:

class SubFoo { // does not extend 
    function __construct() { 
     $this->__foo = new Foo; // sub-object instead 
    } 
    function __call($func, $args) { 
     echo "intercepted $func()!\n"; 
     call_user_func_array(array($this->__foo, $func), $args); 
    } 
} 

बात इस तरह की डीबगिंग और परीक्षण के लिए अच्छा है, लेकिन आप __call() और दोस्तों में जितना संभव हो उतना से बचना चाहते हैं उत्पादन कोड क्योंकि वे बहुत कुशल नहीं हैं।

+0

यह। आपको फेकाडे पैटर्न का पालन करना होगा। एक रैपर वर्ग है जो उस ऑब्जेक्ट का "मालिक" है जिसे आप इन सभी कार्यों को ओवरराइड करना चाहते हैं। आवश्यकतानुसार विधियों को पारित करने के लिए __call() का उपयोग करें, उचित रूप से कोई अतिरिक्त कार्य करें। प्रदर्शन को पसीना न पड़े जब तक कि आपका कोड लगातार नहीं कहा जाता है और आपका ऐप सीपीयू-सीमित है (लगभग कभी भी मामला नहीं) - प्रोग्रामर का समय इस तरह के व्यापार-बंद पर निर्णय लेने पर प्रदर्शन से लगभग हमेशा महत्वपूर्ण होता है। –

0

यदि आपको पैरेंट बार() में कुछ अतिरिक्त जोड़ने की ज़रूरत है, तो क्या यह करने योग्य होगा?

class SubFoo extends Foo { 
    function bar() { 
     // Do something else first 
     parent::bar(); 
    } 
} 

या यह जिज्ञासा से सिर्फ एक प्रश्न है?

+1

समस्या इस तथ्य से उत्पन्न होती है कि अभिभावक वर्ग के कार्यों का ढेर हो सकता है, और मैं उप-वर्ग में सभी को डुप्लिकेट नहीं करना चाहता हूं, केवल उसी व्यवहार को लागू करने के लिए (// // पहले कुछ और करें 'भाग) उन सभी को – nickf

+0

@nickf बिल्कुल, ऐसा लगता है कि मुझे ऐसा कुछ आवश्यक है, मुझे समझ में नहीं आता कि यह PHP में क्यों नहीं है। –

0

आप एक ही प्रभाव है क्या कर सकता है निम्नलिखित है:

<?php 

class hooked{ 

    public $value; 

    function __construct(){ 
     $this->value = "your function"; 
    } 

    // Only called when function does not exist. 
    function __call($name, $arguments){ 

     $reroute = array(
      "rerouted" => "hooked_function" 
     ); 

     // Set the prefix to whatever you like available in function names. 
     $prefix = "_"; 

     // Remove the prefix and check wether the function exists. 
     $function_name = substr($name, strlen($prefix)); 

     if(method_exists($this, $function_name)){ 

      // Handle prefix methods. 
      call_user_func_array(array($this, $function_name), $arguments); 

     }elseif(array_key_exists($name, $reroute)){ 

      if(method_exists($this, $reroute[$name])){ 

       call_user_func_array(array($this, $reroute[$name]), $arguments); 

      }else{ 
       throw new Exception("Function <strong>{$reroute[$name]}</strong> does not exist.\n"); 
      } 

     }else{ 
      throw new Exception("Function <strong>$name</strong> does not exist.\n"); 
     } 

    } 

    function hooked_function($one = "", $two = ""){ 

     echo "{$this->value} $one $two"; 

    } 

} 

$hooked = new hooked(); 

$hooked->_hooked_function("is", "hooked. "); 
// Echo's: "your function is hooked." 
$hooked->rerouted("is", "rerouted."); 
// Echo's: "our function is rerouted." 

?> 
1

एक बात तुम कोशिश कर सकते निजी या संरक्षित करने के लिए अपने कार्यों गुंजाइश स्थापित करने के लिए है। जब कक्षा के बाहर से एक निजी समारोह कहा जाता है तो यह __call जादू विधि को कॉल करता है और आप इसका फायदा उठा सकते हैं।

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