2012-08-10 15 views
17

Mirando el siguiente código, veo que el constructor está devolviendo un valor. Pensé que los constructores solo devuelven objetos. ¿Puede alguien decirme qué me estoy perdiendo?¿Valor devuelto por el constructor?

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; 
     } 
    } 
+4

No creo que los constructores devuelvan objetos: creo que PHP instancia una nueva instancia de la clase dada, y luego llama a su constructor antes de que el usuario pueda hacer algo. –

+0

Gracias por la corrección. Después de volver a leer mi publicación, busqué un comentario para decir exactamente lo que publicaste :) – Nate

Respuesta

32

De hecho, usted está en lo correcto. No se puede hacer nada con el valor de retorno de un constructor (además de usar el Objeto que creó).

Así que no, no le falta nada, es el desarrollador que escribió ese código quién es.

Es técnicamente posible utilizar valores de retorno de constructores, si se llama a la función directamente

$obj->__construct(); 

Eso le permitirá utilizar el valor devuelto por el constructor. Sin embargo, eso es muy poco común y no es recomendable.

+1

En realidad, * técnicamente * esto es posible: http://codepad.org/sh94ogi9 - Solo tienes que llamar a la función directamente, no a través de 'nuevo'. Lo cual requiere que el objeto ya exista de forma natural. – hakre

+0

@hakra: Sí, pero el OP ha preguntado sobre constructores en el sentido de crear nuevos objetos. Sin embargo, lo agregaré a la respuesta. –

+0

* Técnicamente * posible está cerca de nitpickydidodida, solo quería sonar, demasiado tarde para obtener una respuesta. :) – hakre

1

Un constructor no devuelve nada, pero puede volver desde allí (deteniendo la ejecución del método en un punto por algún motivo, pero el objeto puede crearse).

2

ver esta url - Returning a value in constructor function of a class

leerla: -

constructores no obtienen valores de retorno; sirven completamente para crear una instancia de la clase.

Sin reestructurar lo que ya está haciendo, puede considerar usar una excepción aquí.

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

Ahora, puede crear un nuevo usuario de esta manera.

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

A diferencia de otros idiomas, en PHP puede llamar explícitamente al constructor. Es solo otra función. Parece que el autor original primero decidió poner algún código que pudiera fallar en el constructor, luego se dio cuenta de que necesitaba una forma de volver a ejecutar la inicialización después de una falla. $ result = $ user -> __ construct ($ username, $ password) en realidad funcionaría y obtendrás el valor devuelto. Es una manera fea de hacer las cosas obviamente.

En mi opinión, no es una buena práctica tener un código que desencadene efectos secundarios en el constructor. Pondría el código en una función separada, con un nombre que indique claramente lo que hace.

8

Las respuestas dadas hasta ahora son incorrectas. Puede hacer lo que quiera con el valor de retorno de un constructor, por lo que no es cierto que "No se puede hacer nada con el valor de retorno de un constructor (además de usar el objeto que creó)". El valor de retorno de un constructor no es el objeto "creado". El constructor no crea objetos (la palabra clave new sí). El valor de retorno de un constructor es el mismo que el de cualquier otra función: lo que elija devolver. Además, también es falso que un objeto ya exista para llamar a su constructor. Esto es perfectamente válido:

$parent_constructor_return_value = parent::__construct(); 

Por ejemplo:

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

Aunque esto es posible, no se puede concebir un escenario en el que lo mejor sería práctica.Después de todo, siempre puede llamar a un método que no sea parent::__construct() para obtener su valor, y todo lo que pierde es oscuridad. Supongo que podría ser utilizado como una forma de control de errores - Hay otras dos maneras de lograr lo mismo:

  1. excepciones tiro en el constructor de los padres y atraparlos en su constructor derivada.
  2. Establezca las propiedades en el constructor principal indicando que ocurrió un error, y luego verifique el estado de esas propiedades en el constructor derivado.

Si un error en un constructor principal no es excepcional, podría haber decidido que el constructor padre devuelva los valores de error, en lugar de almacenar la información de error transitorio como propiedades del objeto. Por supuesto, entonces la única razón para nombrar el método del padre __construct es si la clase padre no es abstracta, sino que puede ser instanciada, pero en ese contexto, los mensajes de error devueltos nunca se verán. Entonces, mal patrón; malo. Los constructores no tienen la intención de devolver valores, lo que significa que está abriendo una lata de gusanos arquitectónicos mediante el aprovechamiento de este mecanismo.

Cuestiones relacionadas