2017-07-02 2 views
1

Here a meines Codes vereinfacht:Warum wird die Funktion in der übergeordneten Methode zweimal deklariert?

<?php 

class questions { 

    public function index($from = null) { 

     if ($from != 'test') { 
      return $this->test(); 
     } 

     return 'sth'; 
    } 

    public function test(){ 

     function myfunc(){} 

     return $this->index(__FUNCTION__); 
    } 
} 


class tags extends questions { 

    public function index() { 
     return parent::index(); 
    } 

} 

$obj = new tags; 
echo $obj->index(); 

Wie Sie in der Geige zu sehen, wirft es diesen Fehler:

Warning: Declaration of tags::index() should be compatible with questions::index($from = NULL) in /in/Y5KVq on line 29

Fatal error: Cannot redeclare myfunc() (previously declared in /in/Y5KVq:16) in /in/Y5KVq on line 16

Process exited with code 255

Warum? Natürlich sollte myfunc() einmal deklariert werden. Seit test() wird einmal aufgerufen. Also was sagt der Fehler?

Wie auch immer, wie kann ich es beheben?

+0

Sie funktioniert nur erklären können einmal. Wenn Sie es dynamisch in Code deklarieren, der möglicherweise mehrmals ausgeführt wird, sollten Sie es in eine 'if (! Function_exists ('myfunc'))' Prüfung einbinden. – rickdenhaan

+0

@rickdenhaan Ja, ich kann das tun, was du erwähnt hast. Aber ich möchte wissen, warum diese Funktion mehr als einmal ausgeführt wird? Wie wird der Code kompiliert? –

Antwort

4

Das Problem ist, dass $obj eine Instanz von tags ist, und tags::index() nicht über das $from Argument verfügt.

Also hier ist, was passiert, wenn man $obj->index() nennen:

  1. tags::index() Anrufe parent::index() (die questions::index() ist) ohne Argumente.
  2. questions::index() erhält keine Argumente, daher $from ist NULL
  3. Da $from-'test' nicht gleich ist, ruft sie $this->test(). Beachten Sie, dass $this sich auf $obj bezieht, also eine Instanz von tags. So ruft questions::index() tatsächlich tags::test() hier an.
  4. tags::test() existiert nicht, stattdessen wird questions::test() aufgerufen.
  5. questions::test() definiert die Funktion myfunc() und gibt $this->index() mit dem Namen der aktuellen Funktion ('test') zurück. Denken Sie auch daran, dass $this sich auf $obj bezieht, so dass hier aufgerufen wird.
  6. tags::index() nimmt keine Argumente und ruft parent::index() (oder questions::index() ohne Argumente.
  7. Da questions::index() von test::index() ohne Argumente aufgerufen wird, $from einmal wieder NULL und wir am Ende in einer Schleife auf, die die Funktion myfunc() stürzt da ist jetzt bereits definiert.

Wenn Sie die myfunc() Funktionsdeklaration entfernen, werden Sie sehen, dass Sie in einer Endlosschleife enden.

test::index() Ändern eines $from Argument zu akzeptieren, die auf parent::index() weitergegeben wird, wird dieser Code, wie Sie wollen machen:

class tags extends questions { 

    public function index ($from = null) { 
     return parent::index($from); 
    } 

} 
+0

Vielen Dank ... tolle Analyse.Kannst du mir ein Beispiel für deinen letzten Absatz zeigen? –

+0

Sicher, ich habe meine Antwort aktualisiert. – rickdenhaan

+0

Und meine letzte Frage: Weißt du, wie kann ich mit '$ other_arg' umgehen? Die erwartete Ausgabe ist "etw". https://3v4l.org/pIEr7 –

Verwandte Themen