Php/phpDoc - экземпляр @return этого класса?

Как пометить метод как "возвращает экземпляр текущего класса" в моем 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 code-completion

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

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

Ответы

Ответ 1

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

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

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

Там также запрос для него в Eclipse PDT:

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

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

Ответ 2

Обновление:

Как и 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(){}
}

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

У нас есть аналогичная проблема с методом record iterator current(). Поскольку итератор расширен для многих разных классов, нет смысла иметь связанный с ним @return $class. Ранее мы использовали параметр @satrun77 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(){}
}

Ответ 3

Вот 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 в классе bar

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

Ответ 4

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

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

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

Позаботьтесь.