Возвращаемое значение конструктора?

19

Посмотрев на следующий код, я вижу, что конструктор возвращает значение. Я думал, что конструкторы возвращают только объекты. Может ли кто-нибудь сказать мне, что мне не хватает?

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;
        }
    }
    
задан Nate 10.08.2012 в 16:55
источник
  • Я не думаю, что конструкторы возвращают объекты: я считаю, что PHP создает экземпляр данного класса, а затем вызывает его конструктор, прежде чем пользователь сможет что-либо сделать. –  Waleed Khan 10.08.2012 в 16:57
  • Спасибо за исправление. После повторного чтения моего сообщения я искал комментарий, чтобы точно сказать, что вы разместили :) –  Nate 10.08.2012 в 17:05

5 ответов

34

Действительно, вы правы. Ничего не может быть сделано с возвращаемым значением конструктора (кроме использования созданного им объекта).

Итак, нет, вы ничего не пропустили, это разработчик, который написал этот код, который есть.

Технически возможно использовать возвращаемые значения из конструкторов, если вы вызываете функцию напрямую

$obj->__construct();

Это позволит вам использовать возвращаемое значение конструктора. Однако это очень редко и не рекомендуется.

    
ответ дан Madara Uchiha 10.08.2012 в 16:58
источник
  • На самом деле, технически это возможно: codepad.org/sh94ogi9 - Вам просто нужно вызвать функцию напрямую, а не через новую. Это требует, чтобы объект уже существовал естественным образом. –  hakre 10.08.2012 в 17:06
  • @hakra: Да, но ОП задал вопрос о конструкторах в смысле создания новых объектов. Я добавлю это к ответу. –  Madara Uchiha♦ 10.08.2012 в 17:08
  • Технически возможно близко к nitpickydidodida, я просто хотел подслушать, слишком поздно для ответа. :) –  hakre 10.08.2012 в 17:15
9

Ответы, данные до сих пор, неверны. Вы можете делать все, что хотите, с возвращаемым значением конструктора, поэтому неправда: «Ничего нельзя сделать с возвращаемым значением конструктора (кроме использования созданного объекта)». Возвращаемое значение конструктора не является объектом «он». Конструктор не создает объекты (ключевое слово new делает). Возвращаемое значение конструктора такое же, как и для любой другой функции: все, что вы хотите вернуть. Кроме того, также неверно, что объект уже должен существовать, чтобы вызвать его конструктор. Это совершенно верно:

$parent_constructor_return_value = parent::__construct();

Например:

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

Хотя это возможно, я не могу представить себе сценарий, в котором это была бы лучшая практика. В конце концов, вы всегда можете вызвать метод, отличный от parent::__construct() , чтобы получить свою ценность, и все, что вы потеряли, - это неясность. Я полагаю, что это может быть использовано как способ обработки ошибок. Есть два способа сделать одно и то же:

  1. Выбросьте исключения в родительском конструкторе и поймайте их в своем производном конструкторе.
  2. Задайте свойства в родительском конструкторе, указав, что произошла ошибка, а затем проверьте состояние этих свойств в производном конструкторе.

Если ошибка в родительском конструкторе не является исключительной, он, возможно, решил, что родительский конструктор возвращает значения ошибки, а не сохраняет информацию о переходных ошибках в качестве свойств объекта. Конечно, тогда единственной причиной назвать метод родителя __construct является то, что родительский класс не является абстрактным, но может быть сам создан, но в этом контексте возвращаемые сообщения об ошибках никогда не будут видны. Итак, плохая картина; Плохо. Конструкторы не предназначены для возврата значений, что означает, что вы открываете архитектурную банку червей, используя этот механизм.

    
ответ дан Vladimir Kornea 13.01.2014 в 20:30
источник
2

см. этот url - Возврат значения в конструкторе функция класса

Прочтите: -

Конструкторы не получают возвращаемых значений; они служат целиком для создания класса.

Без реструктуризации того, что вы уже делаете, вы можете использовать здесь исключение.

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

Теперь вы можете создать нового пользователя таким образом.

try {
    $user = new User('[email protected]');
} catch (Exception $e) {
    // unable to create the user using that id, handle the exception
}
    
ответ дан Abid Hussain 10.08.2012 в 17:01
источник
1

Конструктор ничего не возвращает, но вы можете вернуться из него (остановка выполнения метода в точке по какой-либо причине, но объект может быть создан).

    
ответ дан Peter Kiss 10.08.2012 в 16:58
источник
0

В отличие от других языков, в PHP вы можете явно вызвать конструктор. Это еще одна функция. Похоже, что первоначальный автор сначала решил поставить некоторый код, который может потерпеть неудачу в конструкторе, а затем понял, что ему нужен способ перезапустить инициализацию после сбоя. $ result = $ user- & gt; __ construct ($ username, $ password) будет работать, и вы получите возвращаемое значение. Это уродливый способ сделать что-то очевидно.

На мой взгляд, не очень хорошая практика иметь код, вызывающий побочные эффекты в конструкторе. Я бы поставил код в отдельную функцию с именем, в котором четко указано, что он делает.

    
ответ дан cleong 10.08.2012 в 17:25
источник