2012-08-10 12 views
17

Patrząc na poniższy kod, widzę, że konstruktor zwraca wartość. Myślałem, że konstruktorzy zwracają tylko obiekty. Czy ktoś może mi powiedzieć, czego mi brakuje?Konstruktor zwraca wartość?

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

Nie sądzę, aby konstruktorzy zwracali obiekty: Wierzę, że PHP tworzy instancję nowej klasy danej klasy, a następnie wywołuje jej konstruktor, zanim użytkownik będzie mógł coś zrobić. –

+0

Dzięki za poprawkę. Po ponownym przeczytaniu mojego posta szukałem komentarza, aby dokładnie powiedzieć, co napisałeś :) – Nate

Odpowiedz

32

Rzeczywiście masz rację. Nic nie można zrobić z wartością zwracaną konstruktora (oprócz użycia obiektu, który on utworzył).

Więc nie, niczego nie brakuje, to programista napisał ten kod, który jest.

Jest to technicznie możliwe do wykorzystania wartości zwracanych z konstruktorów, jeśli wywołanie funkcji bezpośrednio

$obj->__construct(); 

To pozwoliłoby na wykorzystanie wartości zwracanej przez konstruktora. Jest to jednak bardzo rzadkie i raczej niezalecane.

+1

W rzeczywistości, * technicznie * jest to możliwe: http://codepad.org/sh94ogi9 - Wystarczy zadzwonić bezpośrednio do funkcji, a nie przez 'nowy'. Co wymaga, aby obiekt już istniał naturalnie. – hakre

+0

@hakra: Tak, ale OP pytał o konstruktorów w sensie tworzenia nowych obiektów. Dodam go jednak do odpowiedzi. –

+0

* Technicznie * możliwe jest blisko nitpickydidodida, po prostu chciałem zadzwonić, za późno na odpowiedź. :) – hakre

1

Konstruktor nie zwraca nic, ale można z niego powrócić (zatrzymując wykonanie metody w pewnym momencie z jakiegoś powodu, ale obiekt może zostać utworzony).

2

zobaczyć ten URL - Returning a value in constructor function of a class

przeczytał: -

Konstruktorzy nie dostają wartości zwracanych; służą one w całości do tworzenia klasy.

Bez restrukturyzacji, co już robisz, możesz rozważyć użycie wyjątku tutaj.

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

Teraz możesz utworzyć nowego użytkownika w ten sposób.

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

W przeciwieństwie do innych języków, w PHP można jawnie wywołać konstruktora. To tylko inna funkcja. Wygląda na to, że pierwotny autor zdecydował się na umieszczenie kodu, który mógłby zawieść w konstruktorze, a następnie zdał sobie sprawę, że potrzebuje sposobu na ponowne uruchomienie inicjalizacji po awarii. $ result = $ user -> __ construct ($ username, $ password) faktycznie działałoby i otrzymujesz wartość zwracaną. To brzydki sposób na robienie rzeczy w sposób oczywisty.

Moim zdaniem, nie jest dobrą praktyką, aby kod wywoływał efekty uboczne w konstruktorze. Chciałbym umieścić kod w oddzielnej funkcji, z nazwą, która jasno określa, co robi.

8

Podane dotychczas odpowiedzi są niepoprawne. Możesz zrobić, co chcesz, zwracając wartość konstruktora, więc nie jest prawdą, że "Nic nie może być zrobione z wartością zwracaną konstruktora (poza użyciem utworzonego obiektu)." Wartość zwracana konstruktora nie jest obiektem "to". Konstruktor nie tworzy obiektów (jest to słowo kluczowe new). Zwracana wartość konstruktora jest taka sama, jak każdej innej funkcji: cokolwiek wybierzesz, aby powrócić. Ponadto, jest również fałszywe, że obiekt musi już istnieć, aby wywołać jego konstruktora. To jest całkowicie poprawny:

$parent_constructor_return_value = parent::__construct(); 

Na przykład:

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

ile jest to możliwe, nie mogę wyobrazić sobie scenariusz, w którym najlepiej byłoby praktyką.W końcu możesz zawsze wywołać metodę inną niż parent::__construct(), aby uzyskać swoją wartość, a wszystko, co utracisz, jest nieprzejrzyste. Przypuszczam, że to może być wykorzystywane jako sposób obsługi błędów - istnieją dwa inne sposoby, aby osiągnąć to samo:

  1. generują wyjątki w konstruktorze dominującej i złapać je w konstruktorze pochodzi.
  2. Ustaw właściwości w konstruktorze nadrzędnym, wskazując, że wystąpił błąd, a następnie sprawdź stan tych właściwości w konstruktorze pochodnym.

Jeśli błąd w konstruktorze nadrzędnym nie jest wyjątkowy, mógł zdecydować, że konstruktor nadrzędny zwróci wartości błędu, zamiast zapisywać przejściowe informacje o błędzie jako właściwości obiektu. Oczywiście jedynym powodem, dla którego można nazwać metodę rodzica jest __construct, jeśli klasa nadrzędna nie jest abstrakcyjna, ale może sama zostać utworzona - ale w tym kontekście zwrócone komunikaty o błędach nigdy nie będą widoczne. Zły wzór; zły. Konstruktory nie mają na celu zwracania wartości, co oznacza, że ​​otwierasz puszkę architektoniczną robaków, wykorzystując ten mechanizm.

Powiązane problemy