2009-08-03 10 views
12

Biorąc pod uwagę klasę Foo z konstruktora starym styluWywoływanie PHP Konstruktorzy rodzic z stare/nowe Składnia

class Foo 
{ 
    public function Foo() 
    { 
     //does constructing stuff 
    } 
} 

Czy istnieje funkcjonalna różnica między wywołaniem konstruktora macierzystej z konstruktora new style lub konstruktora starym stylu?

class Bar extends Foo 
{ 
    public function Bar() 
    { 
     //does it matter? 
     //parent::__construct(); 
     //parent::Foo(); 
    } 
} 

Innymi słowy, czy jest coś szczególnego w statycznym rozmowy

parent::__construct() 

gdy jest wykonany z konstruktora, czy jest to po prostu standardowe wywołanie statycznej?

Zanim przejdą najlepsze praktyki Latające małpy schodzą, mam do czynienia z pewnym starszym kodem i próbuję zrozumieć konsekwencje wszystkiego, co się dzieje.

Odpowiedz

16

Powiedziałbym, że obie składnie robią dokładnie to samo ...
Edycja: po napisaniu reszty odpowiedzi, właściwie to nie jest do końca prawdą^^ To zależy od tego, co deklarujesz; zobaczyć dwa przykłady:


Jeśli zdefiniujemy Foo jako konstruktora, i nazywają go __construct, wydaje się, że to działa; następujący kod:

class Foo { 
    public function Foo() { 
     var_dump('blah'); 
    } 
} 

class Bar extends Foo { 
    public function Bar() { 
     parent::__construct(); 
    } 
} 

$a = new Bar(); 

Wyjścia

string 'blah' (length=4) 

Tak, wszystko OK, teraz ;-)


Z drugiej okazji, jeśli zdefiniować __construct i wywołać Foo, jak to :

class Foo { 
    public function __construct() { 
     var_dump('blah'); 
    } 
} 

class Bar extends Foo { 
    public function Bar() { 
     parent::Foo(); 
    } 
} 

$a = new Bar(); 

Dostaniesz Fatalny błąd:

Fatal error: Call to undefined method Foo::foo() 

Tak więc, jeśli twoja klasa jest zadeklarowana ze starą składnią, możesz nazwać ją w obie strony; i jeśli jest zdefiniowana z nowej składni (PHP5), należy użyć tej nowej składni - co ma sens, przecież :-)


BTW, jeśli chcesz jakiś „prawdziwy dowód”, można spróbować użyć Vulcan Logic Disassembler, która da ci kody operacyjne odpowiadające skryptowi PHP.


EDIT po komentarzu

Mam przesłanych wyjścia użyciem VLD z obu składni: - vld-construct-new.txt: podczas deklarowania __construct i nazywając __construct. - vld-construct-old.txt: podczas deklarowania Foo i wywoływania __construct.

Doing różn między dwoma plikami, to co mam:

$ diff vld-construct-old.txt vld-construct-new.txt 
25c25 
< Function foo: 
--- 
> Function __construct: 
29c29 
< function name: Foo 
--- 
> function name: __construct 
44c44 
< End of function foo. 
--- 
> End of function __construct. 
71c71 
< Function foo: 
--- 
> Function __construct: 
75c75 
< function name: Foo 
--- 
> function name: __construct 
90c90 
< End of function foo. 
--- 
> End of function __construct. 

(unified diff jest znacznie dłuższy, więc będę trzymać się przy użyciu formatu domyślnego "diff" tutaj)

Jedynymi różnicami w zdemontowanych kodach są nazwy funkcji; zarówno w klasie Foo, jak i w klasie Bar (która dziedziczy po klasie klasy/Foo klasy Foo).

Co ja naprawdę powiedzieć to:

  • Jeśli pisanie kodu PHP 5 (i, w 2009 roku, mam szczerą nadzieję, że tak ^^), a następnie, po prostu użyj składni __construct
  • ty musisz zachować pewne stary kod PHP 4 nie mogą migrować do PHP 5 (zalecana), a następnie użyj składni Foo ...


Jako sidenote, the documentation says(cytowanie):

Dla kompatybilności wstecznej, jeśli PHP 5 nie może znaleźć __construct() funkcję dla danej klasy, to będzie szukać funkcję konstruktora w starym stylu, przez nazwa klasy.

Skutecznie, to znaczy, że tylko przypadek, że miałby problemy ze zgodnością jest jeśli klasa miała metodę nazwie __construct() którego użyto dla różnych semantyki.

Tak naprawdę myślę, że nie ma wielkiej różnicy :-)


napotkali Państwo jakieś dziwny problem, że uważasz, że jest spowodowane przez coś jak różnica pomiędzy dwie składnie?

+0

+1 Z punktu widzenia ścieżki kodowej wszystko wygląda tak, jak powinno. To, czego nie jestem w 100% jednoznaczny, to czy istnieje jakiś szczególny kontekst/zakres, który trwa, gdy wywołujesz konstruktor, którego może brakować, gdy używasz starszej konwencji nazewnictwa konstruktora –