2008-09-16 9 views
7

में डिफाइनिंग वर्ग तरीकों क्या यह संभव है PHP (as it is in C++) में एक class method बाहर class definition?पीएचपी

+1

जहां तक ​​मुझे पता है कि आप क्या पूछ रहे हैं सी ++ में संभव नहीं है। आप स्पष्टीकरण देना चाहेंगे। – erlando

+0

सी ++ में आप कक्षा के बाहर के कार्यों को परिभाषित कर सकते हैं और यदि पहला पैरामीटर उस वर्ग प्रकार का है, तो आपको ओवरलोड की तरह दिखता है (यानी एक स्पष्ट "यह")। उदाहरण के लिए << ऑपरेटर std :: cout जैसे चीजों के लिए विधि का उपयोग किया जाता है। दुर्भाग्यवश, फ़ंक्शन को कॉल करते समय PHP किसी प्रकार को पहचान नहीं करता है। पैरामीटर की संख्या केवल एक चीज है जिसका उपयोग PHP कार्यों के बीच अंतर करने के लिए किया जा सकता है। फ़ंक्शन स्वयं पैरामीटर प्रकार के लिए परीक्षण कर सकता है और उस पर अलग-अलग कार्य कर सकता है, लेकिन समान नाम वाले दो फ़ंक्शन और पैरामीटर की एक ही संख्या PHP में कुछ गैरकानूनी है। –

उत्तर

1

सं

आपने पूर्व में घोषित कक्षाओं का विस्तार है, हालांकि, कर सकते हैं अगर मदद करता है कि घोषणा करने के लिए।

8

नहीं, PHP 5.2 के रूप में। हालांकि, आप मनमाने ढंग से कार्य या विधि को कॉल अग्रेषित करने के लिए __call जादू विधि का उपयोग कर सकते हैं।

class A { 

    public function __call($method, $args) { 
     if ($method == 'foo') { 
      return call_user_func_array('bar', $args); 
     } 
    } 

} 

function bar($x) { 
    echo $x; 
} 

$a = new A(); 
$a->foo('12345'); // will result in calling bar('12345') 

पीएचपी 5.4 में लक्षण के लिए समर्थन है। विशेषता विधि (ओं) का कार्यान्वयन है जिसे स्टैंडअलोन ऑब्जेक्ट के रूप में तत्काल नहीं किया जा सकता है। इसके बजाय, विशेषता का कार्यान्वयन के साथ वर्ग का विस्तार करने के लिए उपयोग किया जा सकता है। लक्षण here पर और जानें।

0

नहीं यह सकारात्मक नहीं है। यदि आप वर्ग निर्माण के बाहर कार्य/विधि को परिभाषित करते हैं तो यह वैश्विक कार्य बन जाता है।

+0

कक्षा के बाहर परिभाषित सभी कार्य वैश्विक नहीं हैं। यदि आप फ़ंक्शन को एक चर में सहेजते हैं, तो यह वैश्विक नहीं है। ('$ func = function() {...};') –

3

रनटाइम पर अनुपलब्ध विधि का पता लगाने के लिए आप शायद __call or __callStatic ओवरराइड कर सकते हैं, लेकिन आपको कोड ढूंढने और कॉल करने के लिए अपना स्वयं का सिस्टम बनाना होगा। उदाहरण के लिए, आप विधि कॉल को संभालने के लिए "प्रतिनिधि" वर्ग लोड कर सकते हैं।

यहां एक उदाहरण दिया गया है - यदि आपने $ foo-> bar() को कॉल करने का प्रयास किया है, तो कक्षा एक FooDelegate_bar क्लास बनाने का प्रयास करेगी, और उसी तर्क के साथ कॉल बार() पर कॉल करेगी। आप वर्ग ऑटो लोड हो रहा है की स्थापना की रखी है, तो प्रतिनिधि एक अलग फाइल में रह सकते हैं जब तक की आवश्यकता ...

class Foo { 

    public function __call($method, $args) { 
     $delegate="FooDelegate_".$method; 
     if (class_exists($delegate)) 
     { 
      $handler=new $delegate($this); 
      return call_user_func_array(array(&$handler, $method), $args); 
     } 


    } 

} 
0

सी ++ या तो ऐसा नहीं कर सकते। क्या आपने संक्रमण के साथ घोषणा को मिश्रित किया?

0

नहीं, जैसा कि सभी ने कहा है, यह सख्ती से संभव नहीं है।

हालांकि, आप PHP में एक मिश्रण को अनुकरण करने के लिए something like this कर सकते हैं या रनटाइम पर कक्षा में विधियों को जोड़ सकते हैं, जो आप जितना करीब जा रहे हैं उतना करीब है। असल में, यह एक ही कार्यक्षमता प्राप्त करने के लिए बस डिजाइन पैटर्न का उपयोग कर रहा है। ज़ोप 3 पाइथन में मिश्रित मिश्रणों के समान कुछ करता है, एक और भाषा जो सीधे उनका समर्थन नहीं करती है।

+0

पायथन के बारे में आपका कथन गलत है, क्योंकि पाइथन एकाधिक विरासत का समर्थन करता है, और वास्तव में रनटाइम पर परिभाषित विधियों का समर्थन करता है। – lkraider

5

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

<?php 
class A { } 
classkit_method_add('A', 'bar', '$message', 'echo $message;', 
    CLASSKIT_ACC_PUBLIC); 
$a = new A(); 
$a->bar('Hello world!'); 

उदाहरण:

<?php 
class Example { 
    function foo() { 
     echo "foo!\n"; 
    } 
} 

// create an Example object 
$e = new Example(); 

// Add a new public method 
classkit_method_add(
    'Example', 
    'add', 
    '$num1, $num2', 
    'return $num1 + $num2;', 
    CLASSKIT_ACC_PUBLIC 
); 

// add 12 + 4 
echo $e->add(12, 4); 
+0

ध्यान दें कि इसके लिए एक पीईसीएल एक्सटेंशन की आवश्यकता है कि प्रत्येक व्यक्ति के पास स्वचालित रूप से उनके सर्वर पर न हो। इसके अलावा, इसे अब रनकिट कहा जाता है। http://www.php.net/manual/en/function.runkit-method-add.php –

1

पीएचपी 5.3 बंद का समर्थन करता है के रूप में, आप प्रभावी रूप से चर पकड़े बंद उदाहरण पद्धतियां निर्धारित कर सकते हैं: $self ले रहा है

$class->foo = function (&$self, $n) { 
    print "Current \$var: " . $self->var . "\n"; 
    $self->var += $n; 
    print "New \$var:  " .$self->var . "\n"; 
}; 

(आप कर सकते हैं ' एक संदर्भ (&) के रूप में $this ऑब्जेक्ट संदर्भ के बाहर) का उपयोग करें, आप उदाहरण को संशोधित कर सकते हैं।

हालांकि, समस्या उत्पन्न होती है जब आप सामान्य रूप से कार्य कॉल करने के लिए प्रयास करें:

$class->foo(2); 

आप एक गंभीर त्रुटि मिलता है। PHP सोचता है कि foo वाक्यविन्यास के कारण $class का एक तरीका है। साथ ही, आपको इंस्टेंस को पहले तर्क के रूप में पास करना होगा।

call_user_func($class->foo, &$class, 2); 
# => Current $var: 0 
# => New $var:  2 

बस उदाहरण चर से पहले & डाल करने के लिए याद रखें:

वहाँ सौभाग्य से call_user_func बुलाया नाम से काम करता है फोन करने के लिए एक विशेष कार्य है।

class MyClass { 
    public function __call ($method, $arguments) { 
    if (isset($this->$method)) { 
     call_user_func_array($this->$method, array_merge(array(&$this), $arguments)); 
    } 
    } 
} 

अब आप $class->foo(2) बजाय कॉल कर सकते हैं:

क्या और भी आसान है अगर आप __call जादू विधि का उपयोग है। जादू __call विधि किसी अज्ञात विधि पर कॉल को पकड़ती है, और $class->foo वैरिएबल में बंद कॉल को उसी नाम के साथ कॉल करती है।

बेशक, $class->var निजी था, $class->foo चर में संग्रहीत बंद होने से यह एक्सेस नहीं कर पाएगा।

+0

ध्यान दें कि फ़ंक्शन को कॉल करने का उपयोग PHP में कानूनी नहीं है। इसे थोड़ी देर पहले स्वीकार किया गया था (शायद PHP 4 में आवश्यक) लेकिन आज जब आप उस कोड को 'call_user_func ($ class-> foo, और $ class, 2) चलाते हैं तो आपको चेतावनियां या त्रुटियां मिलती हैं; '। –

+0

मुझे पता है। यह – jocap

+0

से पहले आवश्यक था और इसके अलावा, नवीनतम PHP संस्करणों में, आप इसे बंद करने में $ का उपयोग कर सकते हैं। – jocap