I am running into trouble making IntelliJ IDEA display inherited methods correctly.
I have an abstract BaseController class holding two protected field variables (f3 and db). In the extending ForumController class, db works fine, but the static f3 does not (see screenshots below).
The framework used is FatFree, if that helps.
Any help or suggestion would be highly appreciated.
Use the tags of phpdoc to document all classes, properties and methods. IntelliJ uses those to determine what possible values a property or variable may hold. In this case documenting the $f3 property could be sufficient:
/**
* #var Base
*/
protected $f3;
After typing the first /** on the line before the property and pressing enter IntelliJ will generate a docblock for you with what it knows already.
In fatfree framework, the instance of Base class ($f3 in your code) is passed to the constructor, so you can use type hinting there:
public function __construct(Base $f3){
$this->f3 = $f3;
Though retrieving the instance from the registry via the static call Base::instance(); and using phpdoc comments as in the accepted answer is fine as well.
Related
Recently I got someones PHP site project (and this someone don't wan't to help me), so I have to understand his code. And maybe my answer would be stupid, but...
But there's some methods before class, that are doxumented as in example:
namespace Base\Classes;
/**
* #method int method1()
* #method $this method2(int $parameter)
*/
class SomeClass extends ParentClass
{
public $_s_a = false;
public $_user_roles = [];
public function SomeClassMethod() {
somethingDone();
}
}
And as you can see in this example, these documented methods are not implemented in defined class. But what my question is about - this methods are called from another classes and templates. And PHPStorm (my IDE) connects this documentation lines with calls, and ctrl+B leads from between references. But I can't find exact implementation of this methods. They cannot be found in parent classes, they are not in this file. And I thought maybe this is some syntax sugar that I'm not familiar with. Am I right? Or there something I'm missing, and all implementations somewhere in another place? (search by method name in folder gives nothing for me)
PHP has a few magic methods, and one of them is __call().
When you have an object that implements __call() (by itself or by one of the parent classes), you may call an inaccessible method on it, and the __call() method will be called instead. This happens, for example, when you call a private method from the outside, or when you call a method that was not defined in code.
When you use such calls to inaccessible methods, IDEs will most likely show a warning that the method does not exist, although the code itself will probably work at runtime. These warnings are quite annoying, so you can add a #method tag to your class, and the IDE will know that this method exists, and will not show a warning.
So, to support the code that you got from someone, take a look at the __call() method implementation. Be aware that this method may be implemented in one of the parent classes, so check them out as well.
I'm building a website with laravel and had some trouble with the documentation of the variables in an eloquent class. I've seen that the eloquent class uses an attributes-array to store all the variables. I'd like to document the available attributes in my classes so I can easily generate documentation and have code-completion with descriptions.
I tried declaring the variables in the classes for documentation. I've tried declaring them public, but then the attributes-array isn't used anymore which is necessary. Declaring them protected works for the attributes-array, but the declared variables aren't used and the documentation and declarations aren't available in other files for code-completion, suggestions and descriptions.
I also would like to avoid getter and setters.
Is there a convenient way of documenting those variables in laravel?
Thanks in advance!
You can document member variables with #property type $variable:
/**
* #property string $foo
* #property int $bar
*/
class MyModel extends Eloquent {
}
I am making usage of
/* #var $var Type */
really often for NetBeans can then autocomplete methods and stuff in code.
Still I think its a very useful feature but sometimes I got objects of
classes extending one more class and implementing multiple interfaces.
Or I even got a transitive class hierarchy.
I don't know a way to tell NetBeans that it shall be using autocomplete for
all these interfaces and upper-layer parent classes.
I would like to do so for of course every of these interfaces / classes got
dedicated methods (which are defined somewhere in case of interfaces...)
I tried something like this:
/* #var $var TypeA|\TypeB|\TypeC */
because I saw NetBeans will generate a similar documentation for methods returning
different class objects due a switch/case. But this seems to work only for the
#return notation.
I also tried
/* #var $var TypeA|TypeB */
Also not working...
NetBeans will autocomplete the last told Type in this case but not a combination of both/all told classes.
How can I document so my autocomplete works as desired (a summary of methods of all classes /interfaces I listed)?
regards!
If I understand you correctly, you are asking to chain hint through your PHP code.
The problem is netbeans has no way of knowing what an object actually is; unless you tell it. The solution is to use the #property command in your object decleration to forward type define the objects members , be it a class or interface.
/**
#property classMyClass1 $clsMyClass1
#property classMyClass2 $clsMyClass2
*/
class baseClass{
public $clsMyclass1;
public $clsMyClass2;
public function __construct() {
$this->clsMyClass1 = new classMyClass1();
$this->clsMyClass2 = new classMyClass2();
}
}
$foo = new baseClass();
Now when you type your code in netbeans it will know what hinting to display on your last typed object
$foo->clsMyClass1->
So long as each class has a forward property decleration you can chain as long as you want
$foo->class1->class2->class3->...
The above code would need the autoload() function to load the correct class files....
Hope this helps you!
In CakePHP 1.3 I usually add model property definitions and PHPDoc to my models and controllers like so:
/**
* #var Vegetable
*/
public $Vegetable;
In Netbeans this gives "Intellisense"-style autosuggestion, displays PHPDoc information, and is generally a boon. Unfortunately in CakePHP 2 it seems that this causes the model lazy-loading to fail because the magic methods __isset() and __get() are never called for properties that already exist.
The lack of autosuggest would be a bitter pill to swallow - has anyone come across this issue, and can you see any workarounds?
Use #property annotation (in class decription).
How can we have autocomplete on property when this one isn't define in the same php file.
for example, with ZF, in the controller we can do
$this->view->voiture = new My_Voiture();
and in the view, we have a variable $this->voiture, but how can i have the autocomplete on it ?
i try /* #var $this->voiture My_voiture */ and no result...
for the moment, my answer is to do in the view
/* #var $voiture My_Voiture */
$voiture = $this->voiture;
but i don't like it. Have you better ?
Documenting the original variable in its original source is actually the best way to go, I think. All other usages of your view in other files should inherit the autocompletion just by documenting it at its one source.
In order to get the autocompletion that I would expect, I would do these things:
In the My_Voiture class, make sure you have docblocks for your variables and your methods. This isn't technically necessary for the autocompletion itself, but it will allow the autocompletion popups to contain much more info that just variables and methods.
In the My_View class, where $voiture is first declared (not used), I would place the #var docblock that identifies its type as My_Voiture. This should be enough to make any usage of its $voiture variable inherit the properties of My_Voiture.
In the My_Controller class, where $view is first declared (not used), I would place the #var docblock that identifies its type as My_View. This should be enough to make any usage of its $view variable inherit the properties of My_View.
Now, in your code file where you are expecting autocompletion on $this->view->voiture -- if it has nothing in it that indicates that $this is a My_Controller object, then Eclipse has nowhere to start when it tries to identify $this (and then all of its properties). I think I've seen some MVC code before where this is prevalent, due to much "dynamic" properties relying on "variable variables" like $$foo.