33

查看以下代码,我看到构造函数正在返回一个值。我认为构造函数只返回对象。有人能告诉我我错过了什么吗?

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

6 回答 6

57

确实你是对的。构造函数的返回值不能做任何事情(除了使用它创建的对象)。

所以不,你没有错过任何东西,是编写该代码的开发人员。

如果直接调用函数,从技术上讲可以使用构造函数的返回值

$obj->__construct();

这将允许您使用构造函数的返回值。然而,这是非常不常见的,并且相当不推荐。

于 2012-08-10T14:58:17.903 回答
25

你可以对构造函数的返回值做任何你想做的事情,所以“对构造函数的返回值无能为力(除了使用它创建的对象)”是不正确的。构造函数的返回值不是“它”创建的对象。构造函数不创建对象(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是父类不是抽象的,但它本身可以被实例化——但在这种情况下,返回的错误消息永远不会被看到。所以,不好的模式;坏的。构造函数不打算返回值,这意味着您正在通过利用这种机制打开一个蠕虫的架构罐。

于 2014-01-13T19:30:34.387 回答
4

请参阅此页面:在类的构造函数中返回值

阅读:-

构造函数没有返回值;它们完全用于实例化类。

如果不重组您已经在做的事情,您可以考虑在此处使用异常。

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('user@example.com');
} catch (Exception $e) {
    // unable to create the user using that id, handle the exception
}
于 2012-08-10T15:01:08.023 回答
3

构造函数不返回任何内容,但您可以从中返回(由于某种原因在某个点停止方法执行,但可以创建对象)。

于 2012-08-10T14:58:33.310 回答
2

与其他语言不同,在 PHP 中您可以显式调用构造函数。这只是另一个功能。看起来原作者首先决定将一些可能失败的代码放在构造函数中,然后意识到他需要一种方法来在失败后重新运行初始化。

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

实际上会起作用,并且您确实会获得返回值。显然,这是一种丑陋的做事方式。

在我看来,在构造函数中包含触发副作用的代码并不是一个好习惯。我会将代码放在一个单独的函数中,其名称清楚地说明了它的作用。

于 2012-08-10T15:25:28.240 回答
1

如果您总是期望一个字符串作为返回值,您可以添加该方法__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;
于 2019-08-14T05:59:22.420 回答