web-dev-qa-db-ja.com

コンストラクタは値を返しますか?

次のコードを見ると、コンストラクタが値を返していることがわかります。コンストラクタはオブジェクトのみを返すと思いました。誰かが私に何が欠けているのか教えてもらえますか?

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

確かにあなたは正しいです。コンストラクターの戻り値では(コンストラクターが作成したオブジェクトの使用を除いて)何もできません。

ですから、何も見逃しているわけではありません。そのコードを書いたのは開発者です。

関数を直接呼び出す場合、技術的にはコンストラクタからの戻り値を使用できます。

$obj->__construct();

これにより、コンストラクタの戻り値を使用できるようになります。ただし、これは非常に一般的ではなく、お勧めできません。

43
Madara Uchiha

これまでの回答は正しくありません。コンストラクターの戻り値を使用して、好きなことができるので、「コンストラクターの戻り値を使用して(作成したオブジェクトを使用することを除いて)何もできない」とは限りません。コンストラクタの戻り値は、作成された「it」オブジェクトではありません。コンストラクターはオブジェクトを作成しません(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()以外のメソッドを呼び出して値を取得することができ、失うものはあいまいなだけです。エラー処理の方法として使用できると思います。同じことを行うには、他に2つの方法があります。

  1. 親コンストラクターで例外をスローし、派生コンストラクターでそれらをキャッチします。
  2. エラーが発生したことを示すプロパティを親コンストラクターに設定し、派生コンストラクターでそれらのプロパティの状態を確認します。

親コンストラクターのエラーが例外的でない場合、一時的なエラー情報をオブジェクトプロパティとして格納するのではなく、親コンストラクターにエラー値を返すように決定した可能性があります。もちろん、親のメソッドに___construct_という名前を付ける唯一の理由は、親クラスが抽象ではなく、それ自体をインスタンス化できる場合ですが、そのコンテキストでは、返されるエラーメッセージは表示されません。だから、悪いパターン。悪い。コンストラクターは値を返すことを意図していません。つまり、このメカニズムを利用してワームの建築缶を開くことになります。

14
Vladimir Kornea

この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
Abid Hussain

コンストラクタは何も返しませんが、そこから戻ることはできます(何らかの理由である時点でメソッドの実行を停止しますが、オブジェクトは作成できます)。

1
Peter Kiss

他の言語とは異なり、PHPでは、コンストラクタを明示的に呼び出すことができます。これは単なる別の関数です。元の作成者が最初にコンストラクタで失敗する可能性のあるコードを配置することを決定したようです。失敗後に初期化を再実行する方法が必要です。

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

実際に機能し、戻り値を取得します。それは明らかに物事を行う醜い方法です。

私の意見では、コンストラクターで副作用をトリガーするコードを作成することはお勧めできません。私はコードを別の関数に入れ、その機能を明確に示す名前を付けます。

0
cleong

常に文字列を戻り値として期待している場合は、メソッド__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;
0
Emad Ha