2010-06-13 4 views
47

Je travaille avec des classes et une structure de classes d'objets, mais pas à un niveau complexe - juste des classes et des fonctions, puis, en un seul endroit, instanciation.Objectif des constructeurs PHP

Quant à __construct et __destruct, s'il vous plaît me dire très simplement: quel est le but des constructeurs et destructeurs? Je connais l'explication théorique au niveau de l'école, mais j'attends quelque chose comme dans le monde réel, comme dans les situations où nous devons les utiliser.

Fournissez également un exemple, s'il vous plaît.

Cordialement

+0

par exemple sont vraiment bien, maintenant je comprends un peu pourquoi les gens cherchent constructor et desructor, mais dites-moi, si je ne suis pas utilisé le constructeur, je perds tout ... bcoz dans le programme nous utilisons beaucoup de fonctions, varaibles et donc .. pour les fonctions et variabl, comment puis-je utiliser construc, y at-il une affectation dynamique là, signifie que nous devrions appeler tous les nom de fonction à l'intérieur du constructeur, – Bharanikumar

+1

quelle est la raison possible de ne pas accepter ... réponse .... –

Répondre

7

Le constructeur d'une classe définit ce qui se passe lorsque vous instancier un objet de cette classe. Le destructeur d'une classe définit ce qui se passe lorsque vous détruisez l'instance d'objet.

Voir la PHP Manual on Constructors and Destructors:

PHP 5 permet aux développeurs de déclarer des constructeurs pour les classes. Les classes qui ont une méthode constructeur appellent cette méthode sur chaque objet nouvellement créé, elle convient donc à toute initialisation dont l'objet peut avoir besoin avant d'être utilisé.

et

PHP 5 introduit un concept destructor similaire à celle d'autres langages orientés objet, tels que C++. La méthode destructeur sera appelée dès que toutes les références à un objet particulier sont supprimées ou lorsque l'objet est explicitement détruit ou dans un ordre quelconque dans la séquence d'arrêt.

En pratique, vous utilisez le constructeur pour placer l'objet dans un état valide minimum. Cela signifie que vous affectez les arguments passés au constructeur aux propriétés de l'objet. Si votre objet utilise une sorte de types de données qui ne peuvent pas être affectés directement en tant que propriété, vous les créez ici, par ex.

class Example 
{ 
    private $database; 
    private $storage; 

    public function __construct($database) 
    { 
     $this->database = $database; 
     $this->storage = new SplObjectStorage; 
    } 
} 

Notez que pour garder vos objets testable, a constructor should not do any real work:

travail dans le constructeur, tels que: création/initialisation collaborateurs, communiquer avec d'autres services, et la logique de mettre en place son propre état supprime les coutures nécessaires au test, forçant les sous-classes/fausses à hériter d'un comportement indésirable. Trop de travail dans le constructeur empêche l'instanciation ou la modification des collaborateurs dans le test.

Dans Example ci-dessus, le $database est un collaborateur. Il a un cycle de vie et le but de son propre et peut être une instance partagée. Vous ne créeriez pas cela à l'intérieur du constructeur. D'autre part, le SplObjectStorage fait partie intégrante de Example. Il a le même cycle de vie et n'est pas partagé avec d'autres objets. Ainsi, il est correct de new dans le ctor.

De même, vous utilisez le destructeur pour nettoyer après votre objet. Dans la plupart des cas, cela n'est pas nécessaire car il est géré automatiquement par PHP. C'est pourquoi vous verrez beaucoup plus de ctors que de dtors dans la nature.

+0

ok désolé, supposons par exemple, cache but de base est l'augmentation des performances du site, même je peux surveiller ce concept de cache, aussi nous pouvons montrer en temps réel comme lors de l'exacuting requête sur ce temps dans un fichier que nous copions les dossiers et l'utilisateur de la prochaine fois en essayant de frapper les dossiers, alors le système cherchera seulement le fichier pas une base de données en direct, est il ya quelque chose comme vous pouvez donner un exemple, s'il vous plaît – Bharanikumar

+0

@Bharanikumar c'est une question complètement différente de ce que vous demandez ci-dessus. Si vous avez besoin d'un cache, regardez dans APC ou memcache et étudiez des exemples de code, comme Zend_Cache. – Gordon

+0

effectivement je sais le cache .no non ... pour comprendre facilement quelqu'un peut dire un exemple comme cache, ce waht j'ai demandé, mais maintenant j'ai aussi beaucoup d'exemples, – Bharanikumar

48

Un constructeur est une fonction qui est exécutée après l'initialisation de l'objet (sa mémoire allouée, ses propriétés d'instance copiées, etc.). Son but est de mettre l'objet dans un état valide.

Souvent, un objet, pour être dans un état utilisable, nécessite certaines données. Le but du constructeur est de forcer ces données à être données à l'objet au moment de l'instanciation et d'interdire toutes les instances sans ces données. Considérons une classe simple qui encapsule une chaîne et possède une méthode qui renvoie la longueur de cette chaîne. Une possible serait:

class StringWrapper { 
    private $str; 

    public function setInnerString($str) { 
     $this->str = (string) $str; 
    } 

    public function getLength() { 
     if ($this->str === null) 
      throw new RuntimeException("Invalid state."); 
     return strlen($this->str); 
    } 
} 

Afin d'être dans un état valide, cette fonction nécessite setInnerString être appelée avant getLength. En utilisant un constructeur, vous pouvez forcer tous les cas être en bon état quand getLength est appelé:

class StringWrapper { 
    private $str; 

    public function __construct($str) { 
     $this->str = (string) $str; 
    } 

    public function getLength() { 
     return strlen($this->str); 
    } 
} 

Vous pouvez également garder le setInnerString pour permettre à la chaîne à changer après instanciation.

Un destructeur est appelé lorsqu'un objet est sur le point d'être libéré de la mémoire. Généralement, il contient du code de nettoyage (par exemple, fermeture des descripteurs de fichiers que l'objet contient). Ils sont rares en PHP car PHP nettoie toutes les ressources contenues dans le script lorsque l'exécution du script se termine.

+1

Une autre façon de dire "mettre l'objet dans un état valide" est dire "assurez-vous que les objets invariants sont vrais". Les invariants de la classe sont les faits devraient toujours être vrais sur les instances: comme la valeur str interne doit toujours être initialisée. – Oddthinking

+0

Bon exemple ... –

41

En savoir par exemple:

class Person { 
    public $name; 
    public $surname; 
    public function __construct($name,$surname){ 
    $this->name=$name; 
    $this->surname=$surname; 
    } 
} 

Pourquoi est-ce utile? Parce qu'au lieu de:

$person = new Person(); 
$person->name='Christian'; 
$person->surname='Sciberras'; 

vous pouvez utiliser:

$person = new Person('Christian','Sciberras'); 

qui est moins code et semble plus propre! Remarque: Comme les réponses ci-dessous le signalent correctement, les constructeurs/destructeurs sont utilisés pour une grande variété de choses, y compris: de/initialisation des variables (surtout quand la valeur est variable), mémoire de/allocation, invariants être surpassé) et un code plus propre. Je voudrais aussi noter que "code nettoyeur" n'est pas seulement "sucre" mais améliore la lisibilité, la maintenabilité, etc.

+0

En dehors de l'utilisation douteuse des propriétés publiques, je pense que cette réponse manque le point. Les constructeurs ne sont pas simplement du sucre syntaxique comme cela semble être implicite, ils sont un moyen d'imposer des invariants. – Artefacto

+5

Il ne semble pas seulement plus propre. Il prévient les erreurs: que se passe-t-il si vous oubliez de définir votre nom de famille? Le constructeur vous force à le faire. – johannes

+1

L'OP demande un exemple concret, et j'en ai montré un. L'utilisation des propriétés publiques est telle que l'exemple est fonctionnel pour les deux cas. Ma réponse ne manque aucun point. Le constructeur peut être utilisé pour n'importe quoi (y compris ce que vous avez mentionné) pour définir les variables par défaut. Exemple rapide: classe A {protected $ path; fonction publique __construct() {$ this-> chemin = getcwd(). 'chemin'; }} – Christian

7

Le constructeur est exécuté au moment où vous instanciez une instance de votre classe. Donc, si vous avez une classe Person:

class Person { 

    public $name = 'Bob'; // this is initialization 
    public $age; 

    public function __construct($name = '') { 
     if (!empty($name)) { 
      $this->name = $name; 
     } 
    } 

    public function introduce() { 
     echo "I'm {$this->name} and I'm {$this->age} years old\n"; 
    } 

    public function __destruct() { 
     echo "Bye for now\n"; 
    } 
} 

Pour démontrer:

$person = new Person; 
$person->age = 20; 
$person->introduce(); 

// I'm Bob and I'm 20 years old 
// Bye for now 

Nous pouvons remplacer la valeur par défaut définie avec l'initialisation via l'argument du constructeur:

$person = new Person('Fred'); 
$person->age = 20; 
$person->introduce(); 

// if there are no other references to $person and 
// unset($person) is called, the script ends 
// or exit() is called __destruct() runs 
unset($person); 

// I'm Fred and I'm 20 years old 
// Bye for now 

Espérons qui aide à démontrer où le constructeur et le destructeur sont appelés, à quoi servent-ils?

  1. __construct() peut être membre de classe par défaut avec des ressources ou des structures de données plus complexes.
  2. __destruct() peut libérer des ressources comme les handles de fichiers et de bases de données. Le constructeur est souvent utilisé pour class composition ou constructor injection of required dependencies.
0

Je l'ai trouvé qu'il était plus facile à saisir quand je pensais sur le mot-clé new avant que le constructeur: il dit simplement ma variable un nouvel objet de son type de données serait donner à lui, sur la base duquel le constructeur j'appelle et ce que je passe dedans, je peux définir à l'état de l'objet à l'arrivée.

Sans le nouvel objet, nous vivrions dans la terre de null, et les accidents! Le destructeur est le plus évident à partir d'un point de vue C++, où si vous n'avez pas une méthode destructeur supprimer toute la mémoire pointée, il restera utilisé après la sortie du programme provoquant des fuites et retard sur le système d'exploitation client jusqu'à son prochain redémarrage.

Je suis sûr qu'il y a plus qu'assez de bonnes informations ici, mais un autre angle est toujours utile de ce que j'ai remarqué!

+0

A propos de la partie fuite, ce n'est pas précis. Lorsque vous quittez votre programme, toute fuite est supprimée (à moins que la mémoire réside dans un autre programme). Les fuites de mémoire sont mauvaises surtout pendant l'utilisation du programme, pas quand il se termine. Par exemple, j'ai déjà eu un programme qui a fui 700 Mo en 1 heure d'utilisation. Mais quand fermé tout retourné à la normale. – Christian