Aktueller Standort: Startseite> Neueste Artikel> Geben Sie Einschränkungen ein, wenn Sie IS_A () verwenden

Geben Sie Einschränkungen ein, wenn Sie IS_A () verwenden

M66 2025-06-02

Schauen wir uns zunächst ein typisches Beispiel an. Um sicherzustellen, dass der Dienst einer bestimmten Schnittstelle entspricht, verwenden Entwickler, um sicherzustellen, dass der Dienst eine bestimmte Schnittstelle entspricht, ähnlich wie folgt:

<Code> if (! is_a ($ serviceInstance, myServiceInterface :: class)) {neue InvalidArgumentException ("Service muss myServiceInterface implementiert"); } </code>

Auf der Oberfläche verhindert dies die Injektion von Fehlertypen während der Registrierungsphase, wodurch die Laufzeitfehler vermieden werden. In der Tat ist dieser Ansatz eine Garantie für die Schnittstellenisolation. Aber hier ist die Frage: Ist es wirklich notwendig, manuell zu überprüfen?

Das PHP selbst hat bereits Unterstützung für das Typsystem geliefert

Ausgehend von Php 7 ist die Eingabeaufforderung leistungsstark genug:

<Code> Funktion Regierservice (MyServiceInterface $ Service) {// ...} </code>

Wenn Sie zu diesem Zeitpunkt in einer Instanz bestehen, die nicht mit dem MyServiceInterface übereinstimmt, wirft PHP selbst ein Typeerror . Müssen wir es also noch einmal mit is_a () manuell überprüfen?

Eigentlich ist es nicht notwendig. Sofern Ihr Code nicht zulässt, dass gemischte Typen übergeben werden, oder die Quelle der Serviceinstanz sehr ungewiss ist (z. B. eine Remote-Instanzinjektion, ein Plug-in-Systembelastung usw.), ist der PHP-Eingabeaufforderungsmechanismus ausreichend.

Nebenwirkungen der Typprüfung

Die Überbeanspruchung von IS_A () bringt einige versteckte Probleme mit sich:

  1. Wiederholte Überprüfung : Das Typsystem wurde überprüft und es wird manuell wiederholt, um die Wartungsbelastung zu erhöhen.

  2. Hindernispolymorphismus : Einige Implementierungsklassen können Instanzen mit Merkmalen oder dynamischen Proxy -Methoden generieren, und die Überprüfung von IS_A () kann dazu führen, dass es als illegales Objekt falsch eingeschätzt wird.

  3. Machen Sie Container Logik überflüssig : Die Verantwortung eines Containers besteht darin, Abhängigkeiten zu analysieren und zu injizieren, anstatt die Überprüfung der Typen zu erzwingen. Zu schwere Verantwortung kann leicht zu einer Kopplung führen.

Angemessene Nutzungsszenarien

Es bedeutet nicht, dass is_a () nutzlos ist. Es ist in den folgenden Szenarien immer noch nützlich:

  • Plugin -System: Wenn die erweiterte Klasse, die von einem Dritten bereitgestellt wird, nicht mit den Typ -Eingabeaufforderungen eingeschränkt werden kann, kann die Verwendung von IS_A () im Voraus fehlschlagen.

  • Dynamische Dienstregistrierung: Wenn Sie beispielsweise eine Konfigurationsdatei zum dynamischen Sofizieren des Dienstes lesen, ist die entsprechende IS_A () -Verifizierung aus Sicherheitsgründen akzeptabel.

  • Vermeiden Sie böswillige Injektion: In großen Systemen können einige Module von mehreren Teams aufrechterhalten werden, und die Verwendung von IS_A (), da die endgültige Verteidigungsstrategie auch eine Bottom-up-Strategie ist.

Praktischer Rat

In der normalen Serviceregistrierungslogik wird empfohlen, nach Möglichkeit den nativen Eingabeaufforderung der nativen Art zu verwenden + automatische Abhängigkeitsinjektion. Halten Sie den Code einfach und die Verantwortlichkeiten Single. Bei Behältern reicht es aus, Objekte zu konstruieren, Abhängigkeiten zu injizieren und Lebenszyklen zu lösen, und es besteht keine Notwendigkeit, die Verantwortung für die "Überprüfung der Polizei" zu übernehmen .

Wenn eine dynamische Überprüfung wirklich erforderlich ist, wird empfohlen, IS_A () in eine Werkzeugfunktion einzubeziehen und auf einheitliche Weise zu verwalten, z. B.:

<Code> Funktion assertImplements ($ Instance, String $ Schnittstelle) {if (! is_a ($ instance, $ interface)) {thrown InvalidArgumentException ("Instanz nicht implementiert: $ interface"); }} </code>

Dies verbessert nicht nur die Lesbarkeit, sondern reduziert auch die Kopplung.