So dokumentieren Sie magische Methoden (_call und _callStatic) für IDEs

80

Nach vielen glücklichen Jahren des Codierens in Notepad ++ und Sublime wurde mir geraten, eine PHP-IDE auszuprobieren. Ich probiere phpStorm aus und es scheint schön. Die Vervollständigung und Dokumentation des Codes ist eine großartige Funktion, funktioniert aber für mich nicht, wenn magische Methoden verwendet werden. Gibt es eine Lösung, um phpStorm dazu zu bringen, zu verstehen, was in magischen Methoden vor sich geht?

Unsere Situation ist ungefähr so:

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();

Mit der magischen callStatic-Methode können wir eine Sammlung von Objekten über ein oder mehrere Argumente abrufen, aus denen der Funktionsaufruf besteht.

Ich sehe, dass es in diesen Fällen eine @ method-Anweisung gibt, aber phpStorm greift nur die erste dieser Anweisungen auf. Außerdem kann ich den Rückgabetyp nur dann auf gemischt setzen, wenn ich es vorziehen würde, ihn als die Klasse festzulegen, für die dies aufgerufen wurde (b in meinem Beispiel).

Alle Ideen oder Vorschläge würden sehr dankbar aufgenommen, danke.

Rob Forrest
quelle
1
Warum sollte ANYONE dass zwingende THINK _callist eine gute Idee? !!
Brian Gordon
Ich muss sagen, + 1 würde Brians Kommentar für den Fall, dass eine vernünftige Person diese Frage finden wird. Magische Methoden sind in jeder Hinsicht: undokumentierbar (versuchen Sie, ein (n) [Parameter | Vorbedingung | Nachbedingung | Ausnahme] für eine magische Methode zu dokumentieren), nicht IDE-freundlich (versuchen Sie, eine magische Methode schrittweise zu debuggen), widerstandsfähig gegen Refactoring (Bitte denken Sie nicht einmal daran, eine magische Methode in einer dauerhaften Software umzugestalten.) und LAZY (ok, die letzte könnte als Meinung ausgelegt werden).
Luke A. Leber
16
-1 auf die Meinung im Kommentar von @ LukeA.Leber, da es einen Mangel an Vision zeigt. Während magische Methoden keine Möglichkeit sind, weniger Code zu schreiben (wenn Sie sie verwenden, um faul zu sein), ermöglichen magische Methoden Architekturen, die einfach sonst nicht möglich oder so unverschämt komplex wären, dass es sich nicht lohnt, sie zu schreiben. Und sie sind bei der Verwendung von PHPDoc absolut IDE-freundlich. Beachten Sie, dass Sie die meiste Zeit keine magischen Methoden benötigen, aber wenn Sie sie benötigen, gibt es keinen Ersatz (in PHP). Wenn sie auf sehr strukturierte Weise verwendet werden, ist ihre Verwendung eine vollständig gültige Lösung.
MikeSchinkel
5
Denken Sie nicht, dass das Überschreiben __calleine schlechte Idee ist. Alles dreht sich um die Implementierung. Die in der obigen Frage gezeigte Implementierung wäre definitiv nicht der beste Weg, aber für kettenfähige APIs bietet sie viel Flexibilität.
Steve Bauman

Antworten:

143

Die Verwendung eines PHPDoc-Kommentars auf Klassenebene - insbesondere des @ method- Tags - funktioniert in PhpStorm einwandfrei :

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

In obigem:

  • @method - PHPDoc-Tag
  • static - sagt, dass dies eine statische Methode ist
  • someClassoder $this- Rückgabetyp
  • get_by_user_id - Methodenname
  • (int $id) - Methodensignatur: ([[type] [parameter]<, ...>])
  • Bla-bla - eine optionale Beschreibung

Mehr zu @method:

PS Obwohl es @method staticin PhpStorm einwandfrei funktioniert (teilt IDE mit, dass die Methode statisch ist), wird es möglicherweise (noch?) Nicht vom tatsächlichen phpDocumentor-Tool unterstützt (leider wurde es eine Weile nicht verwendet).


Alternativ : (natürlich in PhpStorm) Settings | Inspections | PHP | Undefined | Undefined method --> Downgrade severity if __magic methods are present in class- es hilft in keiner Weise bei der Code-Vervollständigung für solche Methoden, markiert diese magischen Methoden jedoch nicht als "undefinierte Methoden" -Fehler.


phpDocumentors Ticket zur Verwendung von RegEx / Teilnamen für @property/ @methodTags (wie es für die Dokumentation nützlich sein kann und wie wenig Hilfe es für die eigentliche IDE beim Umgang mit Code-Vervollständigung bringen kann):

LazyOne
quelle
2
Vielen Dank, dies scheint ein vernünftiger Vorschlag zu sein und funktioniert sicherlich in phpStorm, aber ich bin ein bisschen abgeneigt, die möglicherweise Hunderte von Zeilen von @method oben in jeder Klasse aufzuschreiben. Sie sehen, dass der Methode get_by_ * jeder der Objektparameter vorangestellt werden kann, um Objekte dieses Typs durch den angegebenen Parameter abzurufen. Selbst wenn ich die Möglichkeit von get_by_ _and_ ausschließen würde, würde ich ungefähr 1500 @methodsin 140 verschiedenen Klassen haben. Gibt es keine allgemeinere Möglichkeit, Dokumentation bereitzustellen?
Rob Forrest
Nein. Alle magischen Methoden müssen speziell deklariert werden (das ist der Hauptgrund für die Dokumentation auf diese Weise). PHPDoc versteht keine Teilnamen (z get_by_*(int $id). B. ). Für IDE (Code-Inspektion, nicht Abschluss!) Haben Sie eine alternative Lösung (Warnungen deaktivieren). Für phpDocumentor (oder ein alternatives Tool) - mir ist keine Lösung bekannt (vielleicht ist sie vorhanden, aber ich weiß nichts darüber). Sie haben den Link zu github - legen Sie ein neues Ticket ab und fragen Sie nach dem Hinzufügen solcher Übereinstimmungsfunktionen für "Teilnamen" - sehen Sie, was sie sagen (höchstwahrscheinlich werden sie abgelehnt). Wenn es implementiert wird, kann IDE es später auch haben.
LazyOne
github.com/phpDocumentor/phpDocumentor2/issues - überprüfen Sie jedoch, ob ein ähnliches Ticket nicht vorhanden ist, bevor Sie Ihr Ticket veröffentlichen.
LazyOne
Danke für all das. Diesbezüglich gibt es derzeit ein offenes Ticket, aber alles scheint ruhig geworden zu sein. Ich habe dort einen Kommentar eingefügt und wir werden sehen, was daraus wird.
Rob Forrest
2
Nur als Referenz das Ticket des phpDocumentors (damit andere Benutzer wissen, um welches Ticket es sich handelt; fügten es auch der Antwort selbst hinzu): github.com/phpDocumentor/phpDocumentor2/issues/689
LazyOne
4

Etwas im Zusammenhang mit der ursprünglichen Frage:

Sie können dies auch in der phpstorm-Metadatei definieren. Hier ist ein Beispiel für die Factory-Methode (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();

Auf diese Weise müssen Sie nicht jede Möglichkeit dokumentieren, wenn Magie passiert.

Haben Sie einige Dokumente für Details.

Yauheni Prakopchyk
quelle
Dies funktioniert nicht mit __call. Es ist auch nicht dokumentiert und ungültiges PHP. PHPStorm bietet nur Unterstützung für statisch definierte Methoden, die je nach Eingabe eine Mischung von Typen zurückgeben.
jgmjgm