How do I mark a method as \"returns an instance of the current class\" in my phpDoc?
In the following example my IDE (Netbeans) will see that setSomething always returns
!SOLVED! - upgrade to netbeans 9.0 (stable as of July 2018?)
I have been after this for over a year and finally have an open source solution! :)
class Input extends BasicHtml
{
public function someOnlyInputFunc()
{
}
}
class Table extends BasicHtml
{
public function tableOnlyFunc()
{
}
}
abstract class BasicHtml
{
/**
*
* @param array $arrayForNow
* @return $this
*/
public function setStyle( array $arrayForNow )
{
return $this;
}
}
/////driver
$table = new Table();
$input = new Input();
$input->setStyle(array())->//now shows only Input + baseHtml functions
$table->setStyle(array())-> //now shows only Table + baseHtml functions
///note - in 8.0.2 version it shows blank obj drop downs on exact same code.
This also works with traits. As of 11/1/2018 9.0 comes as a big zip (no clean installer for windows, mac?) and you will have to search for adding the php plugings etc BUT IT DOES WORK! Took me about an hour to get it all set. I also have my old 8.x installed and running along side the new 9.0 without issue...so far (just don't run them both at same time). Plugin tip: https://www.reddit.com/r/PHP/comments/9gtaaw/how_to_run_netbeans_9_with_php_support/
Update:
As of Netbeans 7.4, the IDE supports @return self, static, and this (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(){}
}
Previous Answer:
We have a similar issue with a record iterator's current()
method. Since the iterator is extended for many different classes, it doesn't make sense to have a @return $class
associated with it. We've used @satrun77's Option 2 before, but I've used @method with some success in 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(){}
}
phpDoc syntax allows for multiple types to be defined by separating them with a | character for the @return tag. When you extend the class foo
with class bar
you should write a new phpDoc tag that has the proper class for its @return
.
If a function returns either foo
or bar
then you would use @return foo|bar
.
However in your case just define @return bar
for the overridden function.
Take care.
Thought I'd revisit this Q as I came across a couple of things.
Currently "return $this" isn't supported, but there is a PhpDoc request to add exactly that in v1.5:
http://pear.php.net/bugs/bug.php?id=16223
There's also a request for it in Eclipse PDT:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=276082
Both are relatively old requests. I'm not going to get too excited about this being implemented any time soon, but here goes to hoping :) In the meantime, it seems there is no proper solution to this problem.
Here is 3 work around: (These are just work around. classes must not be designed and implemented to sue the behavior of an IDE)
Option 1: make the method someOtherMethod abstract or empty method in foo class
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();
}
Option 2:
Override the method setSomething in bar class
class bar extends foo {
/**
*
* @param <type> $value
* @return bar
*/
public function setSomething($value) {
return parent::setSomething($value);
}
public function someOtherMethod(){}
}
Option 3: Use interface
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(){}
}