IDEのマジック(_callおよび_callStatic)メソッドを文書化する方法


81

notepad ++と崇高なコーディングで何年も幸せに過ごした後、PHPIDEを試してみるようにアドバイスされました。phpStormを試していますが、良さそうです。コードの完成とドキュメント化は素晴らしい機能ですが、魔法のメソッドを使用するとうまくいきません。phpStormに魔法のメソッドで何が起こっているのかを理解させるための回避策はありますか?

私たちの状況は次のようなものです。

abstract class a {
    public static function __callStatic($method,$args)
    {
        if(strpos($method,"get_by_") === 0)
        {
            //do stuff
        } elseif(strpos($method,"get_first_by_") === 0) {
            //do stuff
        } elseif($method == "get_all") {
            //do stuff
        }
    }
}

class b extends a {
    // some more stuff
}

b::get_by_user_id(27);
b::get_first_by_id(156);
b::get_all();

魔法のcallStaticメソッドを使用すると、関数呼び出しを構成する1つ以上の引数を介してオブジェクトのコレクションを取得できます。

これらの場合に使用する@methodステートメントがあるようですが、phpStormはこれらのステートメントの最初のものだけを取得しています。さらに、戻り値の型を混合に設定できるのは、これが呼び出されたクラス(私の例ではb)として設定できるようにしたい場合のみです。

どんなアイデアや提案も非常にありがたく受け取られます、ありがとう。


1
なぜだろうが誰もがOVERRIDINGと思い_callIS A GOOD IDEAのか?!
ブライアンゴードン

正気の人がこの質問を見つけようとしている場合は、ブライアンのコメントを+1します。マジックメソッドはすべての目的と目的のためのものです:文書化できない(マジックメソッドにa(n)[パラメータ|前提条件|事後条件|例外]を文書化してみてください)、IDEフレンドリーではない(マジックメソッドをステップデバッグしようとします)、リファクタリングに強い(古いソフトウェアで魔法のメソッドをリファクタリングしようとすることさえ考えないでください)、そしてLAZY(わかりました、最後のものは意見として解釈されるかもしれません)。
ルークA.リーバー2016

17
視力の欠如を証明する@ LukeA.Leberによるコメントの意見に-1。魔法のメソッドはコードを少なくする方法ではありませんが(怠惰に使用している場合)、魔法のメソッドは、他の方法では不可能な単純なアーキテクチャや、書く価値がないほど非常に複雑なアーキテクチャを可能にします。また、PHPDocを使用する場合、IDEに完全に対応しています。ほとんどの場合、魔法のメソッドは必要ありませんが、必要な場合は代替手段がありません(PHPの場合)。非常に構造化された方法で使用する場合は、完全な有効なソリューションです。
MikeSchinkel 2017年

5
オーバーライド__callは悪い考えだとは思わないでください。実装がすべてです。上記の質問に示されている実装は間違いなく最善の方法ではありませんが、チェーン可能なAPIの場合、多くの柔軟性が得られます。
スティーブバウマン

回答:


144

クラスレベルのPHPDocコメント(具体的には@methodタグ)を使用すると、PhpStormで正常に機能します。

/**
 * @method static someClass get_by_user_id(int $id) Bla-bla
 * @method static someClass get_first_by_id(int $id) 
 */
abstract class a {
...

上記の場合:

  • @method --PHPDocタグ
  • static -これが静的メソッドであることを示します
  • someClassまたは$this-戻り値の型
  • get_by_user_id -メソッド名
  • (int $id) -メソッドシグネチャ: ([[type] [parameter]<, ...>])
  • Bla-bla -いくつかのオプションの説明

詳細@method

PS ながら@method staticPhpStormでの作品の罰金(メソッドが静的であることをIDEに指示します)、それは(まだ?)実際のphpDocumentorツール(申し訳ありませんが、しばらくの間、それを使用していない)でサポートされない場合があります。


あるいは:(もちろん、PhpStormでは)Settings | Inspections | PHP | Undefined | Undefined method --> Downgrade severity if __magic methods are present in class-そのようなメソッドのコード補完にはまったく役立ちませんが、これらの魔法のメソッドを「未定義のメソッド」エラーとしてマークすることはありません。


@property/@methodタグの正規表現/部分名の使用に関するphpDocumentorのチケット(ドキュメントにどのように役立つか、コード補完を処理するときに実際のIDEにどの程度役立つか):


2
おかげで、これは合理的な提案のように見え、確かにphpStormで機能しますが、各クラスの先頭に潜在的に数百行の@methodを書き出すのは少し嫌です。get_by_ *メソッドの前に任意のオブジェクトパラメータを追加して、指定されたパラメータでそのタイプのオブジェクトを取得できることがわかります。get_by_ _and_の可能性を除いても、@methods140の異なるクラスで約1500になります。ドキュメントを提供するためのより一般的な方法はありませんか?
ロブフォレスト2013年

いいえ。すべてのマジックメソッドは具体的に宣言する必要があります(これがこの方法で文書化する主なポイントです)-PHPDocは部分的な名前を理解しません(例get_by_*(int $id))。IDE(コード検査、完了ではありません!)には、代替ソリューション(警告を無効にする)があります。phpDocumentor(または代替ツール)の場合-私には解決策がありません(おそらくそこにありますが、私はそれについて知りません)。githubへのリンクがあります-新しいチケットを提出し、そのような「部分的な名前」に一致する機能を追加するように依頼します-彼らが言うことを確認してください(おそらく拒否されます)。それが実装される場合、IDEは後でそれを持っているかもしれません。
LazyOne 2013年

github.com/phpDocumentor/phpDocumentor2/issues-ただし、投稿する前に、同様のチケットが存在しないかどうかを確認してください。
LazyOne 2013年

そのすべてに感謝します。これに関して現在開いているチケットがありますが、それはすべて静かになっているようです。私はそこにコメントを貼り付けました、そしてそれから何が起こるかを見るでしょう。
ロブフォレスト2013年

2
参考までに、phpDocumentorのチケット(他のユーザーはあなたが話しているチケットを知っているので、答え自体にも追加します):github.com/phpDocumentor/phpDocumentor2/issues/689
LazyOne

4

元の質問にやや関連しています:

これは、phpstormメタファイルで定義することもできます。ファクトリメソッド(v2016.3)の例を次に示します。

// Define in .phpstorm.meta.php
namespace PHPSTORM_META {
    $STATIC_METHOD_TYPES = [
        \Factory::create('') => [],
    ];
}

// Then use in code
$factory = new \Factory();
$user = $factory->create(\User::class);
// Here you get autocomplete.
$user->subscribe();

このようにして、魔法が起こったときにすべての可能性をdocblockする必要はありません。

詳細については、いくつかのドキュメントがあります。


これは__callでは機能しません。また、文書化されておらず、無効なPHPです。PHPStormは、入力に応じてタイプの混合を返す静的に定義されたメソッドがある場合にのみサポートを提供します。
jgmjgm 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.