2015-03-16 16 views
5

In PhpStorm kann ich tippe-Tipp eine Variable auf diese Weise:Typehint geerbte Klassenvariablen in PhpStorm

/** @var Point $point */ 
$point->x(); 

jedoch sagen, dass ich eine Variable von einer übergeordneten Klasse geerbt und möchte es typ Hinweis :

class PointProxy extends Proxy 
{ 
    public function x() 
    { 
     ... 

     /** @var Point $this->geometry */ 
     return $this->geometry->x(); 
    } 
} 

Dies funktioniert nicht, wirkt PhpStorm, als ob ich $this typangedeutet hatte, und nicht $this->geometry.

Gibt es eine Möglichkeit, einen solchen Typhinweis zu bearbeiten, ohne die Eigenschaft $geometry in der Unterklasse erneut zu deklarieren, oder wird dies nicht unterstützt?

+1

Sie können solche PHPDoc nicht für komplexe Objekte (2. Ebene in Hierarchie) verwenden - nur erste Ebene. Dieser '/ ** @var Punkt $ this-> geometry * /' macht keinen Sinn .. als PHPDoc Kommentar wird nur auf die erste Ebene ('$ this 'in diesem Fall) angewendet. Jetzt können Sie versuchen, es über '@ property' im PHPDoc-Kommentar für die Klasse zu deklarieren - sollte nur sinnvoll sein, wenn es sich um eine öffentliche Eigenschaft und nicht um private/protected handelt. – LazyOne

+0

Wenn möglich, sollte die Eigenschaft in der Elternklasse angegeben werden; Dies sollte sich in Unterklassen ausbreiten. – deceze

+1

@deceze Es * ist * in der Elternklasse typisiert, aber als 'Geometrie'. Die Kindklasse sollte dokumentieren, dass es sich tatsächlich um einen "Punkt" handelt, der von "Geometrie" abstammt. – Benjamin

Antwort

3

Versuchen Sie diesen Code. Sie können auch alt+enter bei undefinierten Eigenschaften drücken und Add @property auswählen, damit Sie phpdoc schneller erstellen können.

/** 
* @property Point $geometry 
*/ 
class PointProxy extends Proxy { 
    public function x() { 
    return $this->geometry-> 
    } 
} 

add property completion

+0

Das Problem mit '@ property', wie von @LazyOne erwähnt, ist, dass die Eigenschaft als" public "betrachtet wird, was hier nicht der Fall ist und Verwirrung stiften könnte! – Benjamin

+0

Wenn diese Eigenschaft virtuell und dynamisch ist (wir greifen auf sie über '__get' zu), ist sie in Wirklichkeit 'öffentlich'. Wenn Sie es "geschützt" oder "privat" machen wollen, deklarieren Sie es in der Klasse. – funivan

+1

Es * ist * in der Elternklasse geschützt! – Benjamin

0

Wenn die übergeordneten Objekttypen die Eigenschaft als Geometrie, aber Sie wollen es als einen Punkt eingegeben in Ihrem Kind Klasse (die von Geometrie absteigt), würde ich empfehlen, einen Accessor zu schaffen, in Ihrem Kinderklasse. Möglicherweise mit etwas Typprüfung.

class PointProxy extends Proxy 
{ 
    /** 
    * Access the geometry object on parent class as a Point 
    * 
    * @return Point 
    */ 
    private point() 
    { 
     if(!is_a($this->geometry, 'Point')) 
     { 
      // Log an error or something, this is not a state we should be in 
     } 
     else 
     { 
      return $this->geometry; 
     } 
    } 

    public function x() 
    { 
    ... 

     return $this->point->x(); 
    } 
} 
0

Ich stieß auf ein sehr ähnliches Problem. Ich hatte eine generische Storage-Klasse, die mit Datenbank-Operationen und dann eine Proxy-Klasse oben behandelt, die alle Storage-Klassen-Methoden durch einen Versuch Catch (unter Verwendung __call()) Proxy, so dass ich Ausnahmen an einem Ort behandeln konnte.

Jetzt, wenn ich auf die Speicherinstanz wie $storage->retrievePhoto($id) zugegriffen habe, konnte die PHPSTorm IDE nicht für mich tippen. Meine Lösung bestand darin, dem Objekt $storage eine weitere Annotation des Klassennamens hinzuzufügen.

Zum Beispiel, siehe unten. Da die spezifische Proxy-Klasse wirklich nur ein Wrapper für die ursprüngliche Speicherklasse ist, stellt sie keine Probleme dar, obwohl sie immer noch nicht 100% ig ist, aber sie funktioniert.

final class PhotoRepository 
{ 
    /** 
    * @var \Repositories\Photos\PhotoStorage 
    *  \Repositories\Photos\PhotoStorageExceptionHandlerProxy 
    */ 
    private $storage; 

    /** 
    * @param \Repositories\Photos\PhotosStorageExceptionHandlerProxy $storage 
    */ 
    public function __construct(PhotosStorageExceptionHandlerProxy $storage) 
    { 
     $this->storage = $storage; 
    }