构造函数返回值?

Posted

技术标签:

【中文标题】构造函数返回值?【英文标题】:Constructor returning value? 【发布时间】:2012-08-07 21:48:28 【问题描述】:

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

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;
        
    

【问题讨论】:

我不认为构造函数返回对象:我相信 php 会实例化给定类的一个新实例,然后在用户可以做任何事情之前调用它的构造函数。 感谢指正。重新阅读我的帖子后,我寻找评论来准确说出您发布的内容:) 【参考方案1】:

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

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

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

$obj->__construct();

这将允许您使用构造函数的返回值。但是,这种情况极少见,完全不推荐。

【讨论】:

实际上,技术上这是可能的:codepad.org/sh94ogi9 - 你只需要直接调用函数,而不是通过new。这要求对象已经自然存在。 @hakra:是的,但是 OP 询问了构造函数的意义,即创建新对象。不过,我会将其添加到答案中。 技术上可能接近 nitpickydidodida,我只是想插话,回答太晚了。 :) 然后显示我应该在 php 构造函数中声明 null 返回类型#phpstan【参考方案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】:

查看此网址 - Returning a value in constructor function of a class

阅读:-

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

如果不重组你已经在做的事情,你可以考虑在这里使用异常。

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

【讨论】:

【参考方案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;

【讨论】:

以上是关于构造函数返回值?的主要内容,如果未能解决你的问题,请参考以下文章

构造函数返回值?

1构造函数和析构函数为什么没有返回值?

JavaScript中使用new操作符实例化对象时构造函数有返回值的情况分析

js 构造函数的返回值

Jquery 的构造函数

为啥在按值返回时总是调用复制构造函数