Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHPStorm type hinting subclasses of baseclass

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.

like image 476
stratis Avatar asked Sep 30 '15 10:09

stratis


2 Answers

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

/**
 * @property myModel $_model
 */
class myNewController extends myController
like image 73
Fabian Schmengler Avatar answered Sep 28 '22 03:09

Fabian Schmengler


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;
    ...
}
like image 29
Charles Avatar answered Sep 28 '22 03:09

Charles