PHP विरासत समारोह घोषणा को असंगत के रूप में चेतावनी देता है

मेरे डीबग.लॉग में PHP सख्त मानकों से संबंधित एक अजीब चेतावनी है।

PHP Strict standards:  Declaration of gb_EntryList::fields() should be compatible with mgr_LinearModelCollection::fields($mKey = NULL) in ... on line 339

अब तक इतना बुरा है, लेकिन लाइन 33 9 में gb_EntryList क्लास की परिभाषा है

class gb_EntryList extends mgr_mySQLModel

और gb_EntryList फ़ील्ड्स() को परिभाषित नहीं करता है। इसे mgr_mySQLModel से प्राप्त होता है:

abstract class mgr_mySQLModel extends mgr_LinearModelCollection implements mgr_mySQLModelUpdateable {
   ...
   function fields($mKey = null) { ... }
}

मूल रूप से, मैं घोषणा में = null डालना भूल गया, जिसने mgr_mySQLModel के बारे में समान संदेश प्रस्तुत किए। लेकिन ये अब चले गए हैं।

कोड अच्छी तरह से चलता है, लेकिन यह संदेश मुझे क्या बताना चाहता है?

PHP संस्करण:

PHP 5.4.4-14+deb7u5 (cli) (built: Oct  3 2013 09:24:58)

अपडेट:

मैंने इस मुद्दे में थोड़ा गहरा खोला। दिलचस्प बात यह है कि निम्नलिखित कोड में एक ही संरचना होनी चाहिए, लेकिन PHP -d error_reporting = 4095 -l के साथ ठीक है:

abstract class A {
  function foo($sText = ""){
     echo "A.foo($sText)\n";
  }
  abstract function bar();
}
abstract class B extends A {
  function foo($sText = ""){
     echo "B.foo($sText)\n";
  }  
}
class C extends B {
  function bar(){
    echo "C.bar()\n";
  }
}

$c = new C();
$c->foo('in C');

वास्तविक वर्ग यहां उन्हें पुन: पेश करने के लिए बहुत बड़े हैं। लेकिन संरचना इंटरफेस विरासत से अलग है। हालांकि, उपरोक्त कोड ठीक प्रतीत होता है। वास्तविक स्थिति थोड़ा अधिक जटिल है:

abstract class mgr_LinearModelCollection implements IteratorAggregate, Countable, ArrayAccess {
    protected $sItemClass;
    function getIterator() { }      
    function count(){ }
    function offsetExists($offset){ }
    function offsetGet($offset){ }      
    function offsetUnset($offset){ }        
    function offsetSet($offset, $value){ }

    function fields($mKey = null){
        $aDummy = call_user_func(array($this->sItemClass,'dummyArray'),$mKey);
        return array_keys($aDummy);
    }
}
interface mgr_mySQLModelUpdateable {
    static function updateTable(array $aOpts = array());
}
abstract class mgr_mySQLModel extends mgr_LinearModelCollection implements mgr_mySQLModelUpdateable{
    protected $aFieldNames = null;
    function fields($mKey = null){
        if(!is_array($this->aFieldNames)) return false;
        return $this->aFieldNames;
    }
}
class gb_EntryList extends mgr_mySQLModel {
    static function updateTable(array $aOpts = array()){ }
}

निश्चित रूप से कई और फ़ंक्शन हैं और {} कोड से भरे हुए हैं, लेकिन इसके अलावा यह वास्तविक अपरिवर्तित कोड है, जो कहा गया त्रुटि संदेश उत्पन्न करता है। मुझे वर्तमान में कोई विचार नहीं है, खिलौना मॉडल ठीक क्यों है, लेकिन असली नहीं है। कोई संकेत?

2
gb_EntryList के किसी अन्य माता-पिता को फ़ील्ड विधि घोषित करें?
जोड़ा लेखक deceze, स्रोत
कृपया हमें पूरी gb_EntryList क्लास दिखाएं, अगर यह बहुत लंबा है, तो अप्रासंगिक तरीकों को काट दें।
जोड़ा लेखक Madara Uchiha, स्रोत
हां, mgr_mySQLModel :: फ़ील्ड() अधिभार mgr_LinearModelCollection :: फ़ील्ड्स ()। अब और माता-पिता नहीं हैं, हालांकि शीर्ष श्रेणी IteratorAggregate, Countable, और ArrayAccess लागू करता है।
जोड़ा लेखक Lars Hanke, स्रोत

2 उत्तर

यह E_STRICT संदेश Liskov प्रतिस्थापन सिद्धांत के उल्लंघन के बारे में चेतावनी देता है। इसका मतलब यह है कि सुपरक्लास में पहले से परिभाषित एक विधि को सुपरक्लास में विधि के तर्कों के साथ कॉल करने योग्य होना चाहिए।

यह संदेश ट्रिगर करेगा:

class Super {
  public function foo($argument) {
    echo $argument;
  }
}

class Child extends Super {

  public function foo() {
    parent::foo('bar');
  }
}

आउटपुट:

Strict Standards: Declaration of Child::foo() should be compatible 
with Super::foo($argument) in ... on line 15
1
जोड़ा
मुझे लगता है कि यह मामला होना चाहिए। mgr_LinearModelCollection फ़ंक्शन को परिभाषित करने वाला पहला व्यक्ति है। mgr_mySQLModel इसे अधिभारित करता है, लेकिन उसी पैरामीटर टेम्पलेट का उपयोग करता है। gb_EntryList सिर्फ विरासत, कोई परिभाषा नहीं है।
जोड़ा लेखक Lars Hanke, स्रोत

तथ्य यह है कि आप कहते हैं कि gb_EntryList में फ़ील्ड() घोषित नहीं है कि क्या गलत है। mgr_mySQLModel एक ABSTRACT क्लास है, यदि आप अमूर्त कक्षाओं के लिए PHP मैन्युअल प्रविष्टि सुराग लाइन में है जो कहता है "जब एक अमूर्त वर्ग से विरासत में मिलता है, तो माता-पिता की कक्षा घोषणा में सारणी चिह्नित सभी विधियों को बच्चे द्वारा परिभाषित किया जाना चाहिए"। तो हालांकि PHP जादुई रूप से काम कर रहा है कि आप मूल क्षेत्र() विधि चाहते हैं, आपको वास्तव में इसे बाल वर्ग में भी घोषित करना चाहिए।

0
जोड़ा
अगर यह समस्या थी तो त्रुटि संदेश बहुत स्पष्ट रूप से ऐसा कह रहा होगा: 3v4l.org/ooZ9O
जोड़ा लेखक deceze, स्रोत
बस मेरे मुंह से शब्द ले लिया। एक समान जवाब लिख रहा था। ;)
जोड़ा लेखक JakeGould, स्रोत
खेतों() पदानुक्रम में कहीं भी सार नहीं है।
जोड़ा लेखक Lars Hanke, स्रोत
मुझे यह एक आम समस्या है, लोग हमेशा भूल जाते हैं कि वे सिर्फ एक सामान्य वर्ग की बजाय एक अमूर्त वर्ग का विस्तार कर रहे हैं।
जोड़ा लेखक Garry Welding, स्रोत