2014-05-09 7 views
6

मैं इस परीक्षण स्क्रिप्ट के साथ इंटरफेस और त्रुटियों को लागू:असंगत कार्यों

<?php 
interface A 
{ 
    function myfunction(); 
} 

class B implements A 
{ 
    function myfunction($var = "default") 
    { 
    echo $var; 
    } 
} 

class C extends B 
{ 
    function myfunction() 
    { 
    echo "myfunction"; 
    } 
} 

$c = new C(); 
$c->myfunction(); 

$b = new B(); 
$b->myfunction(); 

यह ठीक चलाता है और आउटपुट myfunctiondefault

अब जब मैं इंटरफ़ेस एक को हटाने और बी अब और एक को लागू नहीं करते हैं, तो जैसे:

<?php 
class B 
{ 
    function myfunction($var = "default") 
    { 
    echo $var; 
    } 
} 

class C extends B 
{ 
    function myfunction() 
    { 
    echo "myfunction"; 
    } 
} 

$c = new C(); 
$c->myfunction(); 

$b = new B(); 
$b->myfunction(); 

मैं इस त्रुटि मिलती है:

PHP Strict standards: Declaration of C::myfunction() should be compatible with that of B::myfunction() in /var/www/test/index.php on line 16 

Strict standards: Declaration of C::myfunction() should be compatible with that of B::myfunction() in /var/www/test/index.php on line 16 

myfunctiondefault 

क्यों यह और भी पहली बार में काम किया था ? मैं दोनों परिस्थितियों में त्रुटि की अपेक्षा करता हूं ...

+0

प्रश्न: आप किस PHP संस्करण के साथ काम कर रहे हैं? यहां के रूप में: https://eval.in/149885 'PHP संस्करण 5.4.6' पर है और काम करता है, प्रिंटिंग: ** 'myfunctiondefault' ** – Darren

+1

@ डैरेन यह सिर्फ एक सख्त त्रुटि है, जाहिर है कि यह आपके सर्वर पर अक्षम है, क्योंकि मेरे पास एक ही त्रुटि है –

+0

मैं 5.3.10 का उपयोग करता हूं, लेकिन मेरे कोड के दोनों संस्करण काम करता है। मैं सिर्फ यह जानना चाहता हूं कि मेरा पहला संस्करण सही क्यों माना जाता है, और मेरा दूसरा गलत। – Veda

उत्तर

3

इंटरफ़ेस का उपयोग करते समय, B और C इंटरफ़ेस घोषणा के विरुद्ध स्वतंत्र रूप से सत्यापित किए जाते हैं। इससे कोई फर्क नहीं पड़ता कि C extends BC परोक्ष रूप से implements A, और C::myfunctionA::myfunction के साथ संगत है, इसलिए कोई समस्या नहीं है। B::myfunctionA::myfunction के साथ भी संगत है, इसलिए कोई समस्या नहीं है।

इंटरफ़ेस के बिना, B::myfunction कि विधि के लिए विहित घोषणा है, और क्योंकि यह एक पैरामीटर स्वीकार करता है लेकिन अधिभावी C::myfunction नहीं है, एक STRICT चेतावनी उठाया है।

if ($obj instanceof <classWhoseInterfaceIExpect>) { 
    $obj-><interfaceIExpect>(); 
} 

अधिक ठोस संदर्भ में:

मूल रूप से, आप यकीन है कि यह कोड काम करता है बनाना चाहते

if ($obj instanceof A) { 
    $obj->myfunction(); 
} 

A::myfunction के बाद से धर्मविधान कोई तर्क को स्वीकार करने के रूप में घोषित किया जाता है, इसके बाद के संस्करण कोड हमेशा काम करेंगे । हालांकि, इंटरफ़ेस के बिना:

if ($obj instanceof B) { 
    $obj->myfunction('foo'); 
} 

तो B::myfunction विहित घोषणा जो एक तर्क को स्वीकार करता है, लेकिन C एक कार्यान्वयन जो नहीं है, तो आप एक संघर्ष बना लिया है बचाता है। इसलिए चेतावनी। यह प्रश्न का उत्तर देना है क्यों यह जिस तरह से काम करता है, यह PHP की सोच समझाया गया है।


चेतावनी: हाँ, भले ही आप इंटरफ़ेस का उपयोग, यह अभी भी एक ही संघर्ष पैदा करेगा:

interface A { ... } 
class B implements A { ... } 
class C extends B { ... } // conflicting implementation to B 

$obj = new C; 

if ($obj instanceof B) { 
    $obj->myfunction('foo'); 
} 

C दोनों एक instanceofA और B है, फिर भी यह दोनों साथ संगत नहीं है एक ही समय में myfunction के कार्यान्वयन। दो विरोधाभासी कार्यान्वयन के लिए यह आपकी समस्या है। चाहे PHP यहां चेतावनी दी जानी चाहिए या बहस योग्य नहीं है। PHP में आपका केक नहीं हो सकता है और इसे भी खा सकता है। इसकी टाइप सिस्टम आपको कुछ त्रुटियों को जितनी जल्दी हो सके पकड़ने में मदद करने के लिए है; यह निश्चित रूप से सही नहीं है और आप अपने संभावित पैर से अपने पैर को शूटिंग से बचाने में नहीं बचा सकते हैं।

यदि आप ऐसे मुद्दों से बचना चाहते हैं तो आपको मूल रूप से विधि हस्ताक्षर नहीं बदलना चाहिए।वह, या परिवर्तन नीचे की ओर बढ़ रहा है; जिसका अर्थ है कि प्रत्येक विस्तारित वर्ग अपने प्रत्यक्ष माता-पिता वर्ग के विधि हस्ताक्षर के साथ संगत है। तो C::myfunction को कम से कम एक वैकल्पिक तर्क स्वीकार करना चाहिए। शायद PHP को इस मामले को पकड़ना चाहिए, शायद इसे एक बग माना जा सकता है कि आपको सभी मामलों में चेतावनी नहीं मिल रही है। दोबारा, यह बहस योग्य है और आपको इस स्थिति में आने से बचने चाहिए।

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