2009-08-03 9 views
12

Compte tenu de la Foo classe avec un constructeur de style ancienCalling PHP Parent Constructors Avec Ancien/Nouveau Syntaxe

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

est-il une différence fonctionnelle entre appeler le constructeur parent avec un nouveau constructeur de style ou le constructeur de style ancien?

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

Autrement dit, est-il quelque chose de spécial à propos de l'appel statique

parent::__construct() 

quand il est fait à partir d'un constructeur, ou est-il juste un appel standard statique? Avant que les Singes Volants ne fassent de la descente, j'ai affaire à un code hérité et j'essaie de comprendre les conséquences de tout ce qui se passe.

Répondre

16

Je dirais que les deux syntaxes font exactement la même chose ...
Edit: après avoir écrit le reste de la réponse, en fait, ce n'est pas tout à fait vrai ^^ Cela dépend de ce que vous déclarez; voir les deux exemples:


Si vous définissez Foo en tant que constructeur, et l'appeler avec __construct, il semble que ça fonctionne; le code suivant:

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

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

$a = new Bar(); 

Sorties

string 'blah' (length=4) 

Donc, tout est OK pour l'instant ;-)


autre façon, si vous définissez __construct, et appelez Foo, comme celui-ci :

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

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

$a = new Bar(); 

Vous obtiendrez une erreur fatale:Donc, si votre classe est déclarée avec l'ancienne syntaxe, vous pouvez l'appeler dans les deux sens; et si elle est définie avec une nouvelle (PHP5) syntaxe, vous devez utiliser cette nouvelle syntaxe - ce qui est logique, après tout :-)


BTW, si vous voulez une sorte de « vraie preuve », vous pouvez essayer d'utiliser le Vulcan Logic Disassembler, qui vous donnera les opcodes correspondant à un script PHP.


EDIT après le commentaire

J'ai téléchargé les sorties de l'utilisation avec les deux syntaxes VLD: - vld-construct-new.txt: lors de la déclaration __construct, et appelant __construct. - vld-construct-old.txt: lors de la déclaration de Foo et de l'appel de __construct.

Faire un diff entre les deux fichiers, ce que je reçois:

$ 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. 

(diff unifié est beaucoup plus longue, donc je vais en tenir à utiliser le format par défaut de « diff » ici) Ainsi, les seules différences dans les opcodes démontés sont les noms des fonctions; à la fois dans la classe Foo et dans la classe Bar (qui hérite de la méthode __construct/Foo de la classe Foo).

Ce que je voudrais vraiment dire est:

  • Si vous ÉCRITURE PHP 5 Code (et, en 2009, je l'espère sincèrement que vous faites ^^), alors, il suffit d'utiliser la syntaxe __construct
  • vous vous devez maintenir un certain ancien code PHP 4 vous ne pouvez pas migrer vers PHP 5 (vous devez), puis, utilisez la syntaxe Foo ...


Comme le sidenote, the documentation says(citant):

Pour une compatibilité ascendante, si PHP 5 ne peut pas trouver une fonction __construct() pour une classe donnée, il recherche la fonction constructeur de style ancien, par le nom de la classe.

En effet, cela signifie que le seul cas qui aurait des problèmes de compatibilité est si la classe a une méthode nommée __construct() qui a été utilisé pour une sémantique différente.

Donc, je pense vraiment qu'il n'y a pas beaucoup de différence :-)


Avez-vous rencontré une sorte de problème étrange, que vous pensez est causée par quelque chose comme une différence entre les deux syntaxes?

+0

+1 D'un tout point de vue du chemin de code semble fonctionner comme prévu. Ce que je ne suis pas 100% clair, c'est s'il y a un contexte spécial/portée qui se passe quand vous appelez dans un constructeur qui pourrait être manquant lorsque vous utilisez la convention de nommage constructeur plus ancienne –

Questions connexes