2011-01-16 16 views
13

Jak oznaczyć metodę jako "zwraca wystąpienie bieżącej klasy" w moim phpDoc?

W poniższym przykładzie mój IDE (Netbeans) zobaczy, że setSomething zawsze zwraca obiekt foo.

Ale to nie jest prawda, jeśli rozciąłem obiekt - zwróci on $this, który w drugim przykładzie jest obiektem bar, a nie obiektem foo.

class foo { 
    protected $_value = null; 

    /** 
    * Set something 
    * 
    * @param string $value the value 
    * @return foo 
    */ 
    public function setSomething($value) { 
     $this->_value = $value; 
     return $this; 
    } 
} 

$foo = new foo(); 
$out = $foo->setSomething(); 

So Fine - setSomething zwraca foo - ale w poniższym przykładzie zwraca bar ..:

class bar extends foo { 
    public function someOtherMethod(){} 
} 

$bar = new bar(); 
$out = $bar->setSomething(); 
$out->someOtherMethod(); // <-- Here, Netbeans will think $out 
         // is a foo, so doesn't see this other 
         // method in $out's code-completion 

... Byłoby wspaniale rozwiązać to jak dla mnie, Ukończenie kodu to ogromne przyspieszenie.

Ktoś ma sprytny trik, a może nawet lepszy, właściwy sposób udokumentowania tego za pomocą phpDoc?

+2

To byłaby wina NetBeansa, ponieważ w PHP nie ma upcastingu i downcastingu obiektu. – BoltClock

+0

Myślę, że jest to prawdopodobnie najbliższy odpowiedzi (tzn. Nie mogę tego zrobić bez jakiegoś okropnego kompromisu). Przypuszczam, że w Javie musiałbym podnieść wynik 'setSomething' do' bar' zanim mógłbym użyć 'someOtherMethod'. – ledneb

Odpowiedz

5

Myślałem, że powrócę do tego Q, gdy natknąłem się na kilka rzeczy.

Obecnie "return $ this" nie jest obsługiwane, ale istnieje żądanie PhpDoc, aby dodać dokładnie to w wersji 1.5:

http://pear.php.net/bugs/bug.php?id=16223

Jest też prośba o nim w Eclipse PDT:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=276082

Oba są stosunkowo stare wnioski. Nie będę zbytnio podekscytowany tym, że zostanie to zaimplementowane w najbliższym czasie, ale tutaj jest nadzieja :) W międzyczasie wydaje się, że nie ma właściwego rozwiązania tego problemu.

1

Oto 3 obejść: (Są po prostu obejść klasy nie muszą być zaprojektowane i wdrożone do sądu zachowanie IDE).

Wariant 1: uczynić metoda someOtherMethod streszczenie lub pusty metoda w klasie foo

class foo implements ifoo { 
    protected $_value = null; 

    /** 
    * Set something 
    * 
    * @param string $value the value 
    * @return ifoo 
    */ 
    public function setSomething($value) { 
     $this->_value = $value; 
     return $this; 
    } 

    // abstract method or create empty method if you want the method to be 
    // to be optional 
    abstract function someOtherMethod(); 
} 

Opcja 2:

zastąpić metodę se tSomething w klasie bar

class bar extends foo { 
    /** 
    * 
    * @param <type> $value 
    * @return bar 
    */ 
    public function setSomething($value) { 
     return parent::setSomething($value); 
    } 

    public function someOtherMethod(){} 
} 

Wariant 3: Zastosowanie interfejsu

interface ifoo { 
    public function someOtherMethod(){} 
} 

class foo { 
    protected $_value = null; 

    /** 
    * Set something 
    * 
    * @param string $value the value 
    * @return ifoo 
    */ 
    public function setSomething($value) { 
     $this->_value = $value; 
     return $this; 
    } 
} 

class bar extends foo implements ifoo { 

    public function someOtherMethod(){} 
} 
+0

Opcja 2 jest prawdopodobnie najlepszym pomysłem, ale jak sam mówisz, wszystkie są obejściami, które wymagają zmiany rozszerzających się klas, gdy klasa podstawowa się zmieni. Myślę, że prawdą jest to, co chcę zrobić, to ograniczenie Netbeans/phpDoc. Trudno powiedzieć, że to wina Netbeansa, ponieważ phpDoc wyraźnie mówi, że zwraca 'foo'. Być może jakaś składnia '@return $ this' byłaby dobra ...? : -S – ledneb

1

phpDoc syntax allows for multiple types to be defined by separating them with a | character for the @return tag. Po rozszerzeniu class foo z class bar powinieneś napisać nowy tag phpDoc, który ma właściwą klasę dla swojej @return.

Jeśli funkcja zwraca foo lub bar, należy użyć @return foo|bar.

Jednak w twoim przypadku wystarczy zdefiniować @return bar dla nadpisanej funkcji.

Uważaj.

+0

Rzeczywiście - ale nie chciałbym, aby setSomething w 'foo' był dokumentowany jako' @return foo | bar | every-other-extending-class'. Miałem nadzieję, że nie będę musiał przepisywać phpDoc dla każdej podklasy, ale wygląda na to, że byłby to jedyny sposób na zrozumienie IDE. – ledneb

8

Aktualizacja:

Jak NetBeans 7.4 IDE obsługuje @return siebie, statyczny, a to (http://wiki.netbeans.org/NewAndNoteworthyNB74#Editor_2).

class foo { 
    protected $_value = null; 

    /** 
    * Set something 
    * 
    * @param string $value the value 
    * @return this 
    */ 
    public function setSomething($value) { 
     $this->_value = $value; 
     return $this; 
    } 
} 

class bar extends foo { 
    public function someOtherMethod(){} 
} 

Poprzedni Odpowiedź:

Mamy podobny problem z current() metody rekord iteratora. Ponieważ iterator jest rozszerzony na wiele różnych klas, nie ma sensu powiązanie go z nim. Użyliśmy wcześniej opcji @ Satrun77, ale użyłem @method z pewnym sukcesem w Netbeans.

class foo { 
    protected $_value = null; 

    /** 
    * Set something 
    * 
    * @param string $value the value 
    * @return foo 
    */ 
    public function setSomething($value) { 
     $this->_value = $value; 
     return $this; 
    } 
} 

/** 
* @method bar setSomething($value) 
*/ 
class bar extends foo { 
    public function someOtherMethod(){} 
} 
+0

Na szczęście dla tych, którzy wciąż nie przeskoczyli do 7,4 z powodu dobrze znanego problemu z renderowaniem czcionek, ta składnia działa również w Netbeans 7.3.1. –

+0

Czy istnieje sposób na zrobienie czegoś takiego jak "this []" jako wartości zwracanej? – tcigler

Powiązane problemy