web-dev-qa-db-fra.com

Valeur de retour constructeur?

En regardant le code suivant, je vois que le constructeur renvoie une valeur. Je pensais que les constructeurs ne renvoient que des objets. Quelqu'un peut-il me dire ce qui me manque?

public function __construct($username = null, $password = null){
        $urlLogin = "{$this->apiHost}/login/$username";

        $postData = sprintf("api_type=json&user=%s&passwd=%s",
                            $username,
                            $password);
        $response = $this->runCurl($urlLogin, $postData);

        if (count($response->json->errors) > 0){
            return "login error";    
        } else {
            $this->modHash = $response->json->data->modhash;   
            $this->session = $response->json->data->cookie;
            return $this->modHash;
        }
    }
22
Nate

En effet, vous avez raison. Rien ne peut être fait avec la valeur de retour d'un constructeur (hormis l'utilisation de l'objet qu'il a créé).

Donc non, vous ne manquez rien, c'est le développeur qui a écrit ce code qui est.

Il est techniquement possible d'utiliser les valeurs de retour des constructeurs, si vous appelez directement la fonction

$obj->__construct();

Cela vous permettrait d'utiliser la valeur de retour du constructeur. Cependant, c'est très rare et assez déconseillé.

38
Madara Uchiha

Les réponses données jusqu'ici sont incorrectes. Vous pouvez faire ce que vous voulez avec la valeur de retour d'un constructeur, il n'est donc pas vrai que "rien ne peut être fait avec la valeur de retour d'un constructeur (mis à part l'utilisation de l'objet qu'il a créé)". La valeur de retour d'un constructeur n'est pas l'objet "it" créé. Le constructeur ne crée pas d'objets (le mot clé new le fait). La valeur de retour d'un constructeur est la même que celle de toute autre fonction: peu importe ce que vous choisissez de retourner. De plus, il est également faux qu'un objet doive déjà exister pour appeler son constructeur. Ceci est parfaitement valable:

$parent_constructor_return_value = parent::__construct();

Par exemple:

abstract class MyBase {
    function __construct () {
        return "Hello, world.";
    }
}
class MyDerived extends MyBase {
    function __construct () {
        echo parent::__construct();
    }
}
new MyDerived(); // prints "Hello, world."

Bien que cela soit possible, je ne peux concevoir de scénario dans lequel ce serait la meilleure pratique. Après tout, vous pouvez toujours appeler une méthode autre que parent::__construct() pour obtenir votre valeur, et tout ce que vous perdez est l’obscurité. Je suppose que cela pourrait être utilisé comme un moyen de gestion des erreurs - il existe deux autres moyens de réaliser la même chose:

  1. Lancez Exceptions dans le constructeur parent et attrapez-les dans votre constructeur dérivé.
  2. Définissez les propriétés dans le constructeur parent en indiquant qu'une erreur s'est produite, puis vérifiez l'état de ces propriétés dans le constructeur dérivé.

Si une erreur dans un constructeur parent n'est pas exceptionnelle, il aurait peut-être décidé de demander au constructeur parent de renvoyer des valeurs d'erreur, plutôt que de stocker des informations d'erreur transitoires en tant que propriétés d'objet. Bien entendu, la seule raison pour nommer la méthode parente __construct est si la classe parente n'est pas abstraite mais peut elle-même être instanciée - mais dans ce contexte, les messages d'erreur renvoyés ne seraient jamais vus. Donc, mauvais schéma; mal. Les constructeurs ne sont pas destinés à renvoyer des valeurs, ce qui signifie que vous ouvrez une boîte de conserve architecturale en exploitant ce mécanisme.

12
Vladimir Kornea

see this url - Retour d'une valeur dans la fonction constructeur d'une classe

Lisez-le: -

Les constructeurs n'obtiennent pas de valeurs de retour; ils servent entièrement à instancier la classe.

Sans restructurer ce que vous faites déjà, vous pouvez utiliser une exception ici.

public function __construct ($identifier = NULL)
{
  $this->emailAddress = $identifier;
  $this->loadUser();
}

private function loadUser ()
{
    // try to load the user
    if (/* not able to load user */) {
        throw new Exception('Unable to load user using identifier: ' . $this->identifier);
    }
}

Vous pouvez maintenant créer un nouvel utilisateur de cette manière.

try {
    $user = new User('[email protected]');
} catch (Exception $e) {
    // unable to create the user using that id, handle the exception
}
4
Abid Hussain

Un constructeur ne renvoie rien, mais vous pouvez en revenir (arrêter l'exécution de la méthode à un moment donné pour une raison quelconque, mais l'objet peut être créé).

1
Peter Kiss

Contrairement à d’autres langages, dans PHP, vous pouvez appeler explicitement le constructeur. C'est juste une autre fonction. Il semble que l'auteur original ait d'abord décidé de mettre un code qui pourrait échouer dans le constructeur, puis s'est rendu compte qu'il avait besoin d'un moyen de réexécuter l'initialisation après un échec. 

$result = $user->__construct($username, $password)

fonctionnerait réellement et vous obtenez la valeur de retour. C'est une façon laide de faire les choses évidemment.

À mon avis, ce n'est pas une bonne pratique d'avoir un code qui déclenche des effets secondaires dans le constructeur. Je mettrais le code dans une fonction distincte, avec un nom qui indique clairement ce qu'il fait.

0
cleong