75 votes

__construct() vs SameAsClassName() pour les constructeurs en PHP

Y a-t-il un avantage à utiliser __construct() au lieu du nom de la classe pour un constructeur en PHP ?

Exemple ( __construct ) :

class Foo {
    function __construct(){
        //do stuff
    }
}

Exemple (nommé) :

class Foo {
    function Foo(){
        //do stuff
    }
}

Avoir le __construct (premier exemple) est possible depuis PHP 5.

Avoir une méthode avec le même nom que la classe comme constructeur (deuxième exemple) est possible de la version 4 à la version 7 de PHP.

73voto

Bazman Points 919

Je suis d'accord avec gizmo, l'avantage est que vous n'avez pas à le renommer si vous renommez votre classe. DRY.

De même, si vous avez une classe enfant, vous pouvez appeler

parent::__construct()

pour appeler le constructeur parent. Si, plus tard, vous modifiez la classe dont la classe enfant hérite, vous n'avez pas à modifier l'appel au constructeur du parent.

Cela semble être une petite chose, mais le fait de ne pas changer le nom d'appel du constructeur de vos classes parentes pourrait créer des bugs subtils (et pas si subtils).

Par exemple, si vous avez inséré une classe dans votre héritière, mais que vous avez oublié de modifier les appels de constructeurs, vous pourriez commencer à appeler les constructeurs des grands-parents au lieu des parents. Cela pourrait souvent provoquer des résultats indésirables qui pourraient être difficiles à remarquer.

Notez également que

A partir de PHP 5.3.3, les méthodes ayant le même nom que le dernier élément d'un nom de classe à espacement de noms ne seront plus traitées comme des constructeurs. Ce changement n'affecte pas les classes sans espacement de noms.

Source : http://php.net/manual/en/language.oop5.decon.php

10 votes

Le style des constructeurs de PHP 4.x sera déprécié dans PHP 7.0 et supprimé dans la prochaine version majeure. php.net/manuel/de/

20voto

Paolo Bergantino Points 199336

__construct a été introduit en PHP5. C'est la façon dont vous êtes supposé le faire maintenant. Je n'ai pas connaissance de avantages en soi, cependant.

Extrait du manuel PHP :

Pour des raisons de compatibilité ascendante, si PHP 5 ne trouve pas de fonction __construct() pour une classe donnée, il cherchera la fonction constructeur de l'ancien style, par le nom de la classe. En fait, cela signifie que le seul cas où il y aurait des problèmes de compatibilité est si la classe avait une méthode nommée __construct() qui était utilisée pour une sémantique différente.

Si vous êtes en PHP5, je vous recommande d'utiliser __construct pour éviter que le PHP ne cherche ailleurs.

16voto

gizmo Points 8528

Le principal avantage que je vois pour __construct, est que vous n'avez pas à renommer votre constructeur si vous changez le nom de votre classe.

16voto

Jan Turoň Points 6598

Aujourd'hui, la réponse acceptée est obsolète.

Renommer les classes est une mauvaise pratique : vous devez vous rappeler où et comment renommer les classes à chaque fois que vous passez à une nouvelle version. Parfois (comme l'utilisation de Réflexion ou une structure de dépendance complexe), cela peut être impossible sans un remaniement radical. Et ceci est complexité accidentelle que vous voulez éviter. C'est pourquoi espaces de noms ont été introduits dans le PHP. Java, C++ ou C# n'utilisent pas le langage __construct ils utilisent un constructeur nommé et il n'y a pas de problème avec eux.

Depuis PHP 5.3.3, les méthodes portant le même nom que le dernier élément d'un fichier espace nom ne sera plus traité comme un constructeur. Ce changement n'affecte pas les classes non espacées par un nom. .

Exemple

namespace Foo;
class Test {
  var $a = 3;

  function Test($a) {
    $this->a = $a;
  }

  function getA() {
    return $this->a;
  }
}

$test = new Test(4);
echo $test->getA(); // 3, Test is not a constructor, just ordinary function

Notez que les constructeurs nommés ne sont pas dépréciés (PHP 5.5 aujourd'hui). Cependant, vous ne pouvez pas prévoir que votre classe ne sera pas utilisée dans un espace de nom, donc __construct devraient être privilégiés.

Clarification sur les mauvaises pratiques mentionnées ci-dessus (pour Dennis)

Quelque part dans votre code, vous pourriez utiliser ReflectionClass::getName() ; lorsque vous renommez la classe, vous devez vous souvenir de l'endroit où vous avez utilisé Reflection et vérifier si l'attribut getName() Le résultat est toujours cohérent dans votre application. Plus vous devez vous souvenir de quelque chose de précis, plus vous risquez d'oublier quelque chose, ce qui entraîne des bogues dans l'application.

Les parents ne peuvent pas avoir le contrôle sur toutes les classes du monde qui dépendent d'eux. Si allow_url_include est activé, d'autres sites web pourraient utiliser la classe de votre serveur, ce qui pourrait provoquer un crash si vous renommez une classe. C'est encore pire dans les langages compilés mentionnés ci-dessus : la bibliothèque peut être copiée et intégrée dans un autre code.

Il n'y a aucune raison de renommer la classe :

  • si le nom de la classe est en conflit, utiliser les espaces de noms
  • si la responsabilité de la classe se déplace, dérivez une autre classe à la place

Dans les classes PHP en espace de nom, la méthode avec le même nom devrait être évitée de toute façon : intuitivement elle devrait produire un objet créé la classe ; si elle fait autre chose, pourquoi lui donner le même nom ? Ce devrait être un constructeur et rien d'autre. Le problème principal est que le comportement d'une telle méthode dépend de l'utilisation de l'espace de noms.

Il n'y a pas de problème avec les constructeurs __construct en PHP. Mais ce n'était pas l'idée la plus intelligente de modifier les constructeurs nommés.

2 votes

Pouvez-vous réécrire le paragraphe 2 pour plus de clarté ? (celui qui commence par "Renommer ...". Je ne comprends pas pourquoi c'est une mauvaise pratique de renommer des classes, et pourquoi il n'y a pas de problèmes avec Java, C, C++, et comment cela est pertinent pour cette question. Cela signifie-t-il que PHP doit également utiliser des constructeurs nommés comme Java, C, C++ ou y a-t-il des problèmes ? Quels sont les problèmes ?

1 votes

@Dennis Voir ma réponse mise à jour. Elle est pertinente pour la réponse acceptée, parce que Bazman a donné un mauvais point sur le renommage de la classe : il n'avait pas le point sur les espaces de noms dans sa réponse au moment où j'ai fourni ma réponse, il l'a copié de ma réponse plus tard. Maintenant, il s'en attribue le mérite, mais peu importe, cela n'affecte pas l'information elle-même et tout le monde s'en fiche.

10voto

Ryan McCue Points 1178

Le meilleur avantage d'utiliser __contruct() au lieu de ClassName() c'est lors de l'extension des classes. Il est beaucoup plus facile d'appeler parent::__construct() au lieu de parent::ClassName() car il est réutilisable entre les classes et le parent peut être changé facilement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X