PHPStorm type hinting subclasses of baseclass

2019-04-05 14:04发布

With respect to this post:

In PHPStorm, how can I make type hinting work when I have a superclass method that returns a different type from each subclass,

this one is about an edge case in PHPStorm type hinting. Please try to follow along - I'll do my best to be as clear as possible:

So, I've got this base abstract class:

abstract class myBaseController {
    protected $_model;
    ...
}

which another class inherits from:

class myController extends myBaseController {
    $hello = 'hello';
    ...
}

and which is further extended by a third class:

class myNewController extends myController {
    public $myvar;
    $this->_model = new myModel();
    ...

    public function myFunc(){
        // !!form is underlined as: "Method 'form' not found in class"!!
        $form = $this->_model->form($new_variable); 
    }

Below is a sample of the myModel class:

class myModel extends BaseModel {
    $world = 'world';
    public function form($my_variable) {
        do_something();
    }

My true question is how to properly "phpdoc" this scenario:

A subclass myNewController is using an inherited variable _model to assign an instance of another class myModel which has a unique function form. How should PHPStorm properly find out about form in myNewController?

My solution so far involves documenting myBaseController like this:

abstract class myBaseController {
    /**
     * @var object
     */
     protected $_model;
    ...
}

However I think @var object is too broad (PHPStorm won't find its declaration) and my guess is that there should be a better (and more specific) way to do this.

Maybe we could instead do:

/**
 * @var BaseModel
 */

if PHPStorm had a way of looking into the subclasses for the method.

Any ideas? Thank you all in advance.

3条回答
虎瘦雄心在
2楼-- · 2019-04-05 14:51

Although perhaps not the best practice, this one will certainly work for you.

You can "override" the _model member in the subclass and document it as of BaseModel's subclass.

// superclass
abstract class myBaseController {
    /**
     * @var BaseModel
     */
     protected $_model;
    ...
}

// subclass
class myNewController extends myBaseController {
    /**
     * @var MyDerivedModel
     */
    protected $_model;
    ...
}
查看更多
Evening l夕情丶
3楼-- · 2019-04-05 14:52

You can specify the property type in your subclass without introducing new code, using the @property annotation:

/**
 * @property myModel $_model
 */
class myNewController extends myController
查看更多
霸刀☆藐视天下
4楼-- · 2019-04-05 15:06

To document the class method's return, use return $this; return static also works

查看更多
登录 后发表回答