php / phpDoc - экземпляр @return $ этого класса? - PullRequest
13 голосов
/ 16 января 2011

Как мне пометить метод как «возвращает экземпляр текущего класса» в моем phpDoc?

В следующем примере моя IDE (Netbeans) увидит, что setSomething всегда возвращает объект foo.

Но это не так, если я расширю объект - он вернет $this, который во втором примере является bar объектом, а не 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();

Так хорошо - setSomething возвращает foo - но в следующем примере возвращается 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

... было бы здорово решить эту проблему, так как для меня завершение кода - это огромный прирост скорости.

У кого-нибудь есть хитрый трюк или, что еще лучше, правильный способ документировать это с помощью phpDoc?

Ответы [ 5 ]

10 голосов
/ 02 мая 2011

Обновление:

Начиная с Netbeans 7.4, среда IDE поддерживает @return self, static и 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(){}
}

Предыдущий ответ:

У нас похожая проблема с методом current() итератора записи. Поскольку итератор расширен для многих различных классов, не имеет смысла ассоциировать с ним @return $class. Мы использовали @ satrun77's Option 2раньше, но я использовал @method с некоторым успехом в 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(){}
}
5 голосов
/ 02 мая 2011

Думаю, что я вернусь к этому Q, когда наткнулся на пару вещей.

В настоящее время "return $ this" не поддерживается, но есть запрос PhpDoc для добавления именно этого в v1.5:

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

В Eclipse PDT также есть запрос:

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

Оба являются относительно старыми запросами.Я не собираюсь слишком волноваться по поводу того, что это будет реализовано в ближайшее время, но здесь есть надежда :) Между тем, похоже, что нет правильного решения этой проблемы.

2 голосов
/ 02 ноября 2018

! РЕШИТЬ!- обновление до netbeans 9.0 (стабильно по состоянию на июль 2018 года?)

После этого я уже более года и, наконец, получил решение с открытым исходным кодом!:)

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.

Это также работает с чертами.По состоянию на 01.11.2008 9.0 поставляется в виде большого zip-файла (нет чистого установщика для windows, mac?), И вам придется искать для добавления php-плагинов и т.д.У меня ушло около часа, чтобы все было готово.У меня также есть мой старый 8.x, установленный и работающий вместе с новым 9.0 без проблем ... пока (только не запускайте их оба одновременно).Подсказка к плагину: https://www.reddit.com/r/PHP/comments/9gtaaw/how_to_run_netbeans_9_with_php_support/

1 голос
/ 17 января 2011

Синтаксис phpDoc позволяет определять несколько типов, разделяя их символом | для тега @return . Когда вы расширяете class foo с помощью class bar, вы должны написать новый тег phpDoc, который имеет соответствующий класс для его @return.

Если функция возвращает foo или bar, вы должны использовать @return foo|bar.

Однако в вашем случае просто определите @return bar для переопределенной функции.

Береги себя.

1 голос
/ 17 января 2011

Вот 3 варианта: (Это всего лишь обходной путь. Классы не должны разрабатываться и реализовываться в соответствии с поведением IDE)

Вариант 1: сделать метод someOtherMethod абстрактным или пустым методом в классе 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();
}

Вариант 2:

Переопределить метод setSomething в классе бара

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

    public function someOtherMethod(){}
}

Вариант 3: Использовать интерфейс

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(){}
}
...