2015-03-16 10 views
5

W PHPStorm mogę wpisać-wskazówkę zmienną w ten sposób:Typehint dziedziczone zmiennych klasy w PHPStorm

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

jednak powiedzieć odziedziczyłem zmienną z klasy nadrzędnej, a chcesz typu podpowiedzi go :

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

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

ten nie działa, PHPStorm działa jakbym typu zasugerował $this i nie $this->geometry.

Czy istnieje sposób, aby taką pracę typu podpowiedzi bez redeclaring właściwość $geometry w podklasie, czy jest to nieobsługiwane?

+1

Nie można używać takiego PHPDoc dla obiektów złożonych (2. poziom w hierarchii) - tylko pierwszy poziom. Ten '/ ** @var Point $ this-> geometry * /' nie ma sensu .. jako komentarz PHPDoc zostanie zastosowany tylko do pierwszego poziomu ('$ this' w tym przypadku). Teraz możesz spróbować zadeklarować to za pomocą '@ property' w komentarzu PHPDoc dla klasy - powinno to mieć sens tylko wtedy, gdy jest to własność publiczna, a nie prywatna/chroniona. – LazyOne

+0

Jeśli to możliwe, właściwość powinna być podana w klasie nadrzędnej; powinno to rozprzestrzeniać się do klas potomnych. – deceze

+1

@deceze It * to * typ-podpowiedź w klasie nadrzędnej, ale jako "Geometria". Klasa potomna powinna udokumentować, że jest w rzeczywistości "Punktem", potomkiem "Geometrii". – Benjamin

Odpowiedz

3

Spróbuj tego kodu. Możesz także nacisnąć alt+enter o niezdefiniowanych właściwościach i wybrać opcję Add @property, która pomoże ci szybciej utworzyć phpdoc.

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

add property completion

+0

Problem z '@ property', o którym wspomniał @LazyOne, polega na tym, że właściwość jest uznawana za" publiczną ", co nie ma miejsca w tym przypadku i może powodować zamieszanie! – Benjamin

+0

Jeśli ta właściwość jest wirtualna i dynamiczna (uzyskujemy dostęp za pośrednictwem '__get') - jest ona" public "w rzeczywistości. Jeśli chcesz uczynić go 'protected' lub' private' zadeklaruj go w klasie. – funivan

+1

It * jest * chroniony w klasie nadrzędnej! – Benjamin

0

Jeśli typów obiektów rodzic nieruchomość jako Geometry ale chcesz to wpisane jako Point (która schodzi z geometrii) w swojej klasie dziecko, polecam stworzenie akcesor w twojej klasa dziecka. Prawdopodobnie z pewnym sprawdzeniem typu.

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

Wpadłem na bardzo podobny problem. Posiadałem ogólną klasę pamięci masowej, która zajmowała się operacjami bazy danych, a następnie klasą proxy na szczycie, która pośredniczyła we wszystkich metodach klasy pamięci za pomocą funkcji catch catch (przy użyciu __call()), dzięki czemu mogłem obsługiwać wyjątki w jednym miejscu.

Teraz za każdym razem, gdy uzyskiwałem dostęp do instancji pamięci masowej, takiej jak $storage->retrievePhoto($id), identyfikator PHPStorm IDE nie mógł dla mnie wpisać podpowiedzi. Moje rozwiązanie polegało na dodaniu innej adnotacji do nazwy klasy do obiektu $storage.

Na przykład patrz poniżej. Ponieważ specyficzna klasa proxy jest w rzeczywistości tylko opakowaniem oryginalnej klasy pamięci, nie stanowi ona żadnego problemu, chociaż nadal nie jest w 100% zgodna z moimi preferencjami, ale działa.

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; 
    }