質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.92%

PHP @$thisと__callメソッドの理解に関して

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 1,547

color

score 63

すみません。。PHPでコードの読み方をご教示頂きたく存じます。
下記の様なコードがあるのですが、__callメソッドの実態が分からず理解出来ておりません。$methodにsoapの接続先のアクション名が来るみたいで、この一行で、
レスポンスが返って来るみたいです。マジックメソッドと言われても、、分からず。。
@$thisの理解も出来ず、苦しいです。
ご助言や確認項目、ご教示出来れば幸いです。

    /**
     * SOAP呼び出し
     *
     *  リクエスト内容はロギングされる
     *
     * @param string          $method  SOAPメソッド名
     * @param AbstractRequest $request リクエスト
     * @return mixed
     * @throws \Exception
     */
    protected function callMethod($method, $request)
    {
        try {
            $response = @$this->__call($method, [['Request' => $request]]);           
            $this->logging($method);
            return $response;

        } catch (\SoapFault $e) {
                throw new \Exception($e->getMessage());
        } catch (\Exception $e) {
            $this->logging($method);
            throw $e;
        }
    }
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    退会済みユーザー

    2017/05/15 12:32 編集

    同じクラス定義内にfunction __callの記述はありませんか?

    キャンセル

回答 4

checkベストアンサー

+1

callMethodメソッドを定義しているクラスは、以下のように定義してありませんか?

class [クラス名] extends SoapClient {
    ...
}

であれば、__callメソッドはSoapサーバ側の 第一引数で指定した名前のメソッドを、
第二引数を引数として呼び出しています。

http://php.net/manual/ja/soapclient.call.php

SoapClient::__call — SOAP 関数をコールする (非推奨)

例えば

public function SearchProducts(SearchProductRequest $request)
{
$this->retry_count = 0;
return $this->callMethod('SearchProducts', $request);
}


というコードは、(このクラスのSearchProductsメソッドではなく)
Soapサーバ側に定義されたSearchProductsメソッドを、ネットワーク越しに呼び出していることになるわけです。

ソースコードや公開されている仕様から、Soapサーバ側のSearchProductsメソッドを確認してみてください。

「どこの Soapサーバに接続しているのか?」
については、おそらくご提示のクラスのコンストラクタなどに URI が記述されているはずです。
http://php.net/manual/ja/soapclient.soapclient.php


ちなみに、__callメソッドの実態は SoapClientクラスに記述されているだけで、お手元のソースコードには記述されていないかもしれません。

その場合、__callメソッドの実装を調べても、特に得られるものはないと思われます。
(汎用的な Soapプロトコルが実装されているだけなので)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/15 17:19

    仰る通りでした。誠にありがとう御座います。

    漸く意味合いが理解出来ました。
    重ねてですが、大変ありがとう御座いました。

    キャンセル

  • 2017/05/15 17:40

    b

    キャンセル

+1

@は、メソッドが無い、などのWarningが出るのを抑制しています。

で、__call($method,~で、そのクラスのメソッドを呼び出すわけです。
$methodの中身がgetHogeだとしたら、そのクラスにgetHogeが実装されている&それを呼び出す
(が、実装されていなかったら、Exceptionが投げられて、catch(\Exception~で受け止められる感じで)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/15 12:45

    すみません、ご教示頂きまして、なるほどと理解は出来たのですが、追加でご質問させてください。頭の中でループしているみたいで。。

    元々下記のメソッドから渡されるのですが、無限ループが走る様に思えちゃうのですが、理解の仕方を本当に申し訳ないのですが、自分に教えて欲しいです。
    public function SearchProducts(SearchProductRequest $request)
    {
    $this->retry_count = 0;
    return $this->callMethod('SearchProducts', $request);
    }

    キャンセル

+1

関数の前に@があるのは、
PHP特有のエラー制御演算子で、
これを書くと、その処理内でエラーがあっても出力されなくなるものです。

$thisはcallMethod関数が所属するclassの意味ですから、
callMethodが書かれているclass内に、
__callメソッドの処理が別にあると思います。
__callメソッドの処理はそちらで確認できます。

大まかな処理の流れは、
callMethodが呼ばれるときに与えられた引数の$method, $requestを元に
__callメソッドに対して、値を問い合わせしています。
__callから得られた値を$response 変数に入れて返しています。

途中に何かしらのエラーや問題があれば、catchの中に処理が移って、
$eの中に入っているエラーを返します。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/15 12:54

    回答誠にありがとうございます。

    下記のコードから呼ばれているのですが、どの様な推測が出来ますか。
    自分には__callの実態が分からず苦心してます。

    public function SearchProducts(SearchProductRequest $request)
    {
    $this->retry_count = 0;
    return $this->callMethod('SearchProducts', $request);
    }

    キャンセル

0

@を先頭につけると、エラーがあった場合でも出力を行わなくなります。
__call()は、未定義のfunctionがcallされた際に、引数のfunctionを実行するものです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る