Подтвердить что ты не робот

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

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

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

Ответ 1

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

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

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

$obj->__construct();

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

Ответ 2

Ответы, данные до сих пор, неверны. Вы можете делать все, что хотите, с возвращаемым значением конструктора, поэтому неправда: "Ничего нельзя сделать с возвращаемым значением конструктора (кроме использования созданного им объекта)". Возвращаемое значение конструктора не является объектом "он". Конструктор не создает объекты (это ключевое слово 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(), чтобы получить свое значение, и все, что вы потеряли, - это неясность. Я полагаю, что это может быть использовано как способ обработки ошибок. Есть два способа сделать одно и то же:

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

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

Ответ 3

см. этот 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
}

Ответ 4

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

Ответ 5

В отличие от других языков, в PHP вы можете явно вызвать конструктор. Это еще одна функция. Похоже, что первоначальный автор сначала решил поставить некоторый код, который может потерпеть неудачу в конструкторе, а затем понял, что ему нужен способ перезапустить инициализацию после сбоя.

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

будет работать, и вы получите возвращаемое значение. Это уродливый способ сделать что-то очевидно.

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

Ответ 6

Если вы всегда ожидаете строку в качестве возвращаемого значения, вы можете добавить метод __toString(), тогда, если вы попытаетесь напечатать этот класс, он вернет то, что вы поместили туда, только строки, и я вижу, что это ваш случай здесь, так что я считаю, что это должно работать для вас..

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

public function __toString(){
     return $this->modeHash;   
}

...
echo yourClass($username, $password); // will return yourClass->modeHash;