Using to phpdoc to specify that a variable represents an object/class

Is the correct way  to tell phpstorm that a variable should be interpreted as representing an object

/** @var $my_variable ClassName */
or is it:
/** @var ClassName */ (which immediately precedes the variable?)

I have tested both ways and both seemed to work, but I wonder which way is more endorsed/supported in ways I haven't tested (or does it not matter)?

6 comments
Comment actions Permalink

Hi there,

First of all, the correct order is [TYPE] [SUBJECT]. PhpStorm understands both orders (for compatibility reasons) but correct one is this:
/** @var ClassName $my_variable */

Now, back to the actual question:

I have tested both ways and both seemed to work

What context is that?

  • If it's for class field/variable, then no need for variable name there (as that PHPDoc comment supposed to apply to the variable just below it -- no need for duplication -- same as you do not specify function/class name when doing PHPDoc for function/class).
  • If it is for ordinary variable, then you HAVE to specify variable name there as there could be many variables defined in there + such PHPDoc can be placed before or after variable definition/assignment.
0
Comment actions Permalink

Thank you, that makes things much clearer.

The context was trying to get PHP storm to offer autocompletions for an object. The first attempt worked if @var was placed anywhere, and the 2nd attempt worked if it was placed right above the variable.

The real context of interest here though is that I have mostly HTML views (in an MVC pattern) that have some basic php logic in them, with most of the heavy lifting being done by a View class which includes/renders the mostly HTML file. So the question was aimed at making workign with PHP in this file a bit easier (with auto completion), since no objects are instantiated in the HTML views, they are just used [either by using $this->(View class method), or this->(View class property, which contains an object)->(object's methods]. So my real interest is making this easier and having phpstorm autocomplete better in included views.

0
Comment actions Permalink

Sure. Just use /** @var ClassName $my_variable */

Placing such comments on the very top of your view/php template will do the job (I'm using exactly the same). You can override what $this is using it if necessary.

Please note that you can typehint only first level variables this way. You cannot typehint some sub-prperty/sub-variable (e.g. this will NOT work: /** @var ClassName $my_variable->my_property */  or /** @var ClassName $my_variable['my_property'] */ ). If you need that, then you have to do it at that class level (PHPDoc comment for that class).

0
Comment actions Permalink

Bazzik wrote:

Please note that you can typehint only first level variables this way. You cannot typehint some sub-prperty/sub-variable (e.g. this will NOT work: /** @var ClassName $my_variable->my_property */  or /** @var ClassName $my_variable['my_property'] */ ). If you need that, then you have to do it at that class level (PHPDoc comment for that class).


Could you please provide an example of how  to typehint for sub-properties/variables at the class level? I have been using your technique for many days now, but I now realized I did not understand what you meant in the quoted passage. Do you mean that in referenced class itself I can use /** @var ClassName $my_variable->my_property */  or /** @var ClassName $my_variable['my_property'] */ , but I couldn't use this in the class that references (Controller) the referenced class (UtilityClass)?



What I mean:

class Controller
{
     /** @var UtilityClass $utility_class */
     public utility_class;
}

class UtilityClass
{
     (What should I put here?)

     public clean_html;
}

Or am I not understanding how to overcome the limitation correctly?

0
Comment actions Permalink

What I meant by that is that you cannot typehint class properties/array elements in the same manner from THAT place.

This means that /** @var ClassName $my_variable->my_property */ or /** @var ClassName $my_variable['my_property'] */ will NOT work because you are trying to typehint internals from completely outisde.

class Controller
{
     /** @var UtilityClass $utility_class */
     public utility_class;
}

This one is correct (you can omit $utility_class part though):

     /** @var UtilityClass */ -- this is enough for class variables as this PHPDoc belongs to this element only (no real need to duplicate the variable name in such case)

     public $utility_class; // don't forget the $ sign -- it's a class variable



In case if you have a class which you cannot edit directly (e.g. part of some library or framework), you may still typehint its public properties or methods IF you extend such class (using @property and @method tags), e.g.

class LibraryClassWhichYouCannotEdit
{
     public $bla; // no type hint here or function below

     public function someFunc($param)
     {
          return 'something';
     }
}

/**
* @property SomeClass $bla
* @method string someFunc(SomeClass $param)
*/

class MyClass extends LibraryClassWhichYouCannotEdit
{
}



I may suggest you to download some modern framework and look how they do it. In particular (those that I was checking recently): Yii2 or Symfony2

0
Comment actions Permalink

Thank you again!

0

Please sign in to leave a comment.