web-dev-qa-db-fra.com

Objectif des constructeurs PHP

Je travaille avec les classes et la structure des classes d'objets, mais pas à un niveau complexe - juste des classes et des fonctions, puis, au même endroit, l'instanciation.

Quant à __construct et __destruct, veuillez me dire très simplement: à quoi servent les constructeurs et les 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 quelles situations nous devons les utiliser.

Veuillez également fournir un exemple.

Cordialement

54
Bharanikumar

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

Fréquemment, un objet, pour être dans un état utilisable, nécessite des données. Le but du constructeur est de forcer la transmission de ces données à l'objet au moment de l'instanciation et d'interdire toute instance sans ces données.

Prenons une classe simple qui encapsule une chaîne et possède une méthode qui renvoie la longueur de cette chaîne. Une mise en œuvre 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);
    }
}

Pour être dans un état valide, cette fonction nécessite que setInnerString soit appelée avant getLength. En utilisant un constructeur, vous pouvez forcer toutes les instances à être en bon état lorsque getLength est appelée:

class StringWrapper {
    private $str;

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

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

Vous pouvez également conserver le setInnerString pour permettre à la chaîne d'être modifiée après l'instanciation.

Un destructeur est appelé lorsqu'un objet est sur le point d'être libéré de la mémoire. En règle générale, il contient du code de nettoyage (par exemple, la fermeture des descripteurs de fichiers que contient l'objet). Ils sont rares dans PHP car PHP nettoie toutes les ressources détenues par le script à la fin de l'exécution du script).

51
Artefacto

Apprenez par l'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');

Ce qui est moins de code et semble plus propre!

Remarque: Comme les réponses ci-dessous l'indiquent correctement, les constructeurs/destructeurs sont utilisés pour une grande variété de choses, y compris: de/initialisation des variables (en particulier lorsque la valeur est variable), de/allocation de mémoire, invariants (pourrait être dépassé) et code plus propre. Je voudrais également noter que le "code plus propre" n'est pas seulement du "sucre" mais améliore la lisibilité, la maintenabilité, etc.

42
Christian

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";
    }
}

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 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 que cela aide à démontrer où le constructeur et le destructeur sont appelés, à quoi servent-ils?

  1. __construct() peut par défaut des membres de classe avec des ressources ou des structures de données plus complexes.
  2. __destruct() peut libérer des ressources comme les descripteurs de fichiers et de bases de données.
  3. Le constructeur est souvent utilisé pour composition de classe ou injection par le constructeur des dépendances requises .
8
Greg K

Le constructeur d'une classe définit ce qui se passe lorsque vous instanciez 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 le PHP Manual on Constructors and Destructors :

PHP 5 permet aux développeurs de déclarer des méthodes 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 de destructeur similaire à celui d'autres langages orientés objet, tels que C++. La méthode destructrice 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 n'importe quel ordre dans la séquence d'arrêt.

En pratique, vous utilisez le constructeur pour mettre l'objet dans un état valide minimum. Cela signifie que vous affectez des 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 exemple.

class Example
{
    private $database;
    private $storage;

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

Notez que pour garder vos objets testables, n constructeur ne devrait pas faire de vrai travail :

Travailler dans le constructeur, par exemple: créer/initialiser des collaborateurs, communiquer avec d'autres services et la logique pour configurer son propre état supprime les coutures nécessaires aux tests, forçant les sous-classes/mocks à 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 le Example ci-dessus, le $database est un collaborateur. Il a un cycle de vie et un objectif qui lui sont propres et peut être une instance partagée. Vous ne créeriez pas cela à l'intérieur du constructeur. En revanche, 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 normal de le 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.

7
Gordon

le constructeur est fonction de la classe qui s'exécute automatiquement lorsque l'objet de la classe est créé nous n'avons pas besoin d'appeler ce constructeur séparément nous pouvons dire le constructeur comme méthode magique car en php la méthode magique commence par des caractères de soulignement doubles

0
Shriyash Deshmukh

J'ai trouvé qu'il était plus facile à saisir lorsque j'ai pensé au mot clé new avant le constructeur: il indique simplement à ma variable qu'un nouvel objet de son type de données lui serait donné, en fonction du constructeur que j'appelle et ce que j'y passe, je peux définir l'état de l'objet à l'arrivée.

Sans le nouvel objet, nous vivrions au pays de null, et nous nous plantons!

Le destructeur est le plus évident d'un point de vue C++, où si vous n'avez pas de méthode destructrice, supprimez toute la mémoire pointée, il restera utilisé après la fin du programme, provoquant des fuites et un retard sur le système d'exploitation du client jusqu'au 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 d'après ce que j'ai remarqué!

0
Jake Kalstad