Just curious if there's a way in netbeans to give type hints for regular variables, so that intellisense picks it up. I know you can do it for class properties, function parameters, return types, etc. but I can't figure out how to do it for regular variables. It's something that would really help in situations where you have a method that can return different object types (like a service locator).
ex something like:
/**
* #var Some_Service $someService
*/
$someService = ServiceLocator::locate('someService');
Where using $someService afterward, netbeans would provide all available methods defined in the class Some_Service.
A single line is all you need:
/* #var $varName Type_Name */
See this article in the NetBeans PHP Blog: https://blogs.oracle.com/netbeansphp/entry/defining_a_variable_type_in
Note: At least, in version 8.2; The key seems to be:
The single asterisk (/* instead of /**).
Placing the type after the variable name.
Having nothing before and after the type-hinting
(except white-space, but even that is not allowed
when the comment is not in a single line).
I know this is an older question, but I was looking for a similar answer for Eclipse/Zend Studio and this solved it as well.
**Note though that it must be on a single line with the opening and closing explicitly in this style...
/* #var $varName Type_Name */
No other formats whether...
/**
* #var $varName Type_Name
*/
or...
// #var $varName Type_Name
seemed to work at all. Hope that helps someone.
Are you looking to document those pesky magic variables? (I did; This question currently ranks top result for that in Google. I hope this helps someone!)
The #property tag allows you to document magic php variables - those implemented using __get() and __set(). The tag should be used in the documentation immediately preceding the class definition:
/**
* Class Contact
* #property string $firstName
* #property string $lastName
*/
class Contact extends Model {
...
This notation triggers autocomplete, tested in Netbeans 8.1 and PhpStorm 2016.1.
According to this bug report, the syntax will change in NetBeans 9:
/* #var $variable VarType */ // vdoc1 (legacy syntax)
/** #var VarType $variable */ // vdoc (new syntax)
Also, it's worth mentioning that you can append [] to a class name to indicate an array of objects:
/* #var $foos Foo[] */
$foos = // ...
foreach ($foos as $foo) {
// $foo will be hinted as Foo here
}
And don't forget your use statement, e.g. use Foo;
In netbeans 8.0.2, the vdoc template gives you this:
/* #var $variable type */
Netbeans will not recognize this however, and will not give you the correct autocomplete list for your objects. Instead use this, just before your variable declaration :
/** #var objectType $varName */
I have not really seen a great use for the stock vdoc Template, especially for class variables that are going to be used as PDO or PDOStatement objects.
One solution I use is actually to go into
Tools / Options / Editor / Code Templates (with PHP selected as your Language), and add a new Template. I called mine hint . Then under Expanded Text, use the following template:
/** #var ${VAR_TYPE variableFromNextAssignmentType default="ClassName"} $$${VARIABLE variableFromNextAssignmentName default="variable"} */
For NetBeans IDE 8.2 syntax is like this:
class foobar{
/** #var string $myvar: optional description here **/
protected static $myvar;
}
This will provide the type hints properly for static variables at least.
Related
I've a question. During a PHP class development I've set in the constructor a class property like this:
public function __construct() {
$this->a = 'ABC';
}
Now my IDE told me that the property was declared dynamically and I should add this property to my class. Now I have two options:
A variable at the top of the class:
protected string $a = '';
Or an annotation in the class doc:
/**
* Class ABC
*
* #property string a
*
* #package Johnny
*/
class ABC {
So whats the difference here and which one should I use? Sometimes I have an error that a property is not defined when using the annotation above so the fix was a protected or private variable.
Thanks for you help!
A protected property can only be accessed from methods in the same class or subclasses. Declaring the property protected prevents it from be assigned or read outside the class.
Adding the #property annotation in a docblock simply lets the IDE know that the property exists. It will use this to suppress warnings like the one you got, and do property name completion, just like it does for properties that are declared explicitly in the class definition. It has little effect on the way PHP itself deals with the property; access control is specified by whether the property is declared public, private, or protected.
You can also create public and private properties in the class definition.
public string $a;
private string $a;
Public means the property can be accessed from outside the class (just like your dynamically-created property), private means it can only be accessed from the class itself (not subclasses).
If you don't declare a property explicitly, and create it dynamically using an assignment, it's automatically public. If you want to prevent this, see Is there a way to disable adding properties into a class from an instance of the class?
This is an explicit declaration of a property type:
protected string $a = '';
This is an internally enforced restriction. If you try to assign something other than a string to $a, you'll get a TypeError exception. Declaring a property type hint like this is a feature that was introduced in 7.4. You should prefer this method if you know your environment will be 7.4+.
This is a docblock:
/**
* #var string
*/
public $a;
It's a comment that has no effect on the runtime of your script. It exists only so that IDEs like PHPStorm or NetBeans can provide hints in your development environment. If you use explicit type hints like above, then these docblock declarations are redundant and unneeded. I.e., there's no need to do this:
/**
* #var string
*/
public string $a;
Note there are quite a few libraries that use comment docblocks to provide special runtime meaning. These libraries use reflection to parse docblock comments on the fly and react to them. In other words, PHP itself is not affected by docblock comments, but your script has the ability to look at them, and is thus capable of basing conditions off them. For example, with Doctrine, you can use docblock comments to explain what your database fields look like:
/**
* #ORM/Column(type="int")
* #ORM/Id
*/
protected $id;
For reasons of ease of maintenance AND IDE class auto-completion and member hinting, I've used PHPDoc in my project. Given this example class:
class my_class {
public $id;
public $name;
public $number;
public function __construct() {
//Do something
}
public function Rename($name) {
$this->name = $name;
}
}
I would prefer to document all properties ($id, $name and $number) with the class documentation itself, which is above the class declaration, and then place documentation for methods (if necessary) above each method. Here is what I ultimately want my class to look like:
/**
* Represents an example class for Stackoverflow
*
* #property int $id The id of the object
* #property string $name The name of the object
* #property int $number The number of the object
*/
class my_class {
public $id;
public $name;
public $number;
public function __construct() {
//Do something
}
/**
* Renames the object
* #param string $name Name to rename object
*/
public function Rename($name) {
$this->name = $name;
}
}
This is precisely what I prefer to have as documentation, however Netbeans' autocomplete fails to operate correctly, as it lists each property twice. For example, if I start typing $my_class_object->i the auto-complete will list two $id properties: one as described in my PHPDoc, and another is described as an unknown variable with "PHPDoc Not Found".
There is a solution that works to solve the Netbeans issue - add a #var PHPDoc block above each property, however I think it unnecessarily clutters up my class, especially some of my classes that have 10+ properties.
Is there a [good] solution to both of my issues (clean doc, proper Netbeans hinting), or am I going about this incorrectly?
The "property" tag is specifically and explicitly for "magic" properties, meaning any that don't actually appear in the code itself. That's the key reason why the tag occurs only in the class docblock. As such, I'm guessing IDEs that recognize the "property" tag do so from that "it's NOT seen in the code" perspective. Granted, I could understand an expectation that autocomplete should recognize the existence of such a property, and therefore make it available for you. However, my bet is that the IDEs will stick with using only the code itself to build a model, and only use docblock info to supplement the elements that it already sees in the code.
Using the "var" tag is the one proper way to document your "coded" properties. If you want to minimize the lines required in order to use that tag on all the properties, use a one-line docblock:
/** #var int */
public $id;
Also, you could use the docblock template to cut down on docblocks, where tag similarity fits your code:
/** #var string */
public $name;
/**##+ #var int */
public $id;
public $number;
/**##-*/
That doesn't seem like much savings in this short list, but it does help when there are lots of properties. Also, it works fine around methods.
I prefer to use #var above each property and no #property at all. I feel that this allows you to more closely associate the comments with the thing that is being commented on. I.e., the comments for a property are always right next to the property. If you're using the #property style and you've got a big class with a ton of properties, it's entirely possible that the comment which describes a property is pages away from it.
I am not sure about the exact syntax but I am sure that netbeans will adhere to the standard php documentation.
http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_tags.pkg.html
http://www.phpdoc.org/
Quick one on NetBeans 7.0 and autocomplete for PHP;
I'm trying to figure out (if possible) how to force __get() implemented in a class to return (refer to) a certain type, the type being the same class in which __get() is implemented, always.
Right now, I have (in View):
/**
* #param string $key
* #return View
*/
public function __get($key){
return $this->getView($key);
}
Accessed like so:
$view->foo-> // should populate with methods from View
^
Now I've been reading about the #property, but I'm not sure if that's correct for what I'm doing. The other thing is (and this would be a nice feature if possible) typically views are nested, so it's not uncommon in my implementation to see this:
$view->foo->bar->baz-> // should populate with methods from View
^
Any idea on how to force this, or am I stuck?
Update:
So #property seems to be heading the correct direction, however there doesn't seem to be support for wildcarding the property names. So to elaborate on my question, does anyone know of any NetBeans plugins, or undocumented (or just plain hard to find) PHPDoc syntax for supporting wildcard #property names?
I'm thinking in one of these directions:
/**
* #property View *
* #property View ...
* #property View $var,...
*/
Of course, none of these variations work, however the last would seem most logical, as they seem to support a similar syntax for variadic function parameter lists.
Netbeans can work that magic for you with the #property like shown in the example below.
As you already have figured out you will have to define each property in the doc block.
Another possible solution for your $x->y->z->view example is listed below.
Copy & paste this into Netbeans and it will show the methods of the Bar class:
<?php
/**
* #property Bar $prop
*/
class foo {
}
class bar {
public function xyz() {
}
public function abc() {
}
}
$x = new foo();
$x->prop->
When you move the cursor here and press ctrl+space you will see:
If you want autocomplete for a longer resulton chain you can also use
/** #var Viewclass $foo */
$foo = $x->y->z->view;
$foo->autoCompleteWorksNow();
anywhere in your code.
I have this code:
/**
* Days to parse
* #var int
*/
const DAYS_TO_PARSE = 10;
...
I don't think that using #var is correct for a constant and I don't see any #constant PHPDoc tag. What is the correct way to do this?
The PHP-FIG suggests using #var for constants.
7.22. #var
You may use the #var tag to document the "Type" of the following
"Structural Elements":
Constants, both class and global scope
Properties
Variables, both global and local scope
Syntax
#var ["Type"] [element_name] [<description>]
#const is not the right answer.
It's not part of the legacy phpDocumentor docs: http://manual.phpdoc.org/HTMLframesConverter/default/
It's not part of the current phpDocumentor docs: http://www.phpdoc.org/docs/latest/index.html
It's not listed in the list of tags on Wikipedia: http://en.wikipedia.org/wiki/PHPDoc#Tags
It's not listed in the PHP-FIG draft PSR: https://github.com/phpDocumentor/fig-standards/blob/master/proposed/phpdoc.md#7-tags
The only "official" place it's listed is phpdoc.de, but the spec there only ever made it to 1.0beta, and the site also includes tags like #brother and #sister, which I've never seen used before, so the overall trust in that site is somewhat diminished ;-) The de facto
standard has always been phpDoc.org.
In short, even if some unofficial standard does mention it, if the documentation generators don't support it, then it's not worth using.
#var is correct for now, and once the PSR (last link in the above list) is out of draft, and is the basis for which phpDocumentor, Doxygen, APIGen and others are understanding PHPDoc, then #type would be correct which is the successor to #var.
There is no need to annotate the type of constants, since the type is always:
either a scalar or an array
known at declaration time
immutable
#const is also not part of the PHPDoc standard. PHP-FIG suggests #var but this is not backed by PHPDoc and doesn't add any information you can't already deduce from the declaration itself.
Therefore, for the sake of readability I recommend just using a plain PHPDoc docblock to document your constants:
class Foo
{
/**
* This is a constant.
*/
const BAR = 'bar';
}
It will describe the constant when you generate PHPDocs yet keeps the comments clean and readable.
I use Netbeans. It will parse phpDoc for global and class constants when this format is used:
/** #const Global constant description */
define('MY_CONST', 10);
class MyClass
{
/** #const Class constant description */
const MY_CONST = 10;
}
The following proposition respects the official documentation syntax:
class Foo
{
const
/**
* #var string Should contain a description
*/
MY_CONST1 = "1",
/**
* #var string Should contain a description
*/
MY_CONST2 = "2";
}
To get them into phpDoc, use:
#const THING
Usual construct:
#const[ant] label [description]
Using Eclipse + PDT, I know that you can specify the return type of a method or the type of a variable within a method via type hints.
How about class fields? Can I declare the type of a field in order to enable autocompletion for that variable?
I tried something on the lines of:
class MyClass {
protected $Field; /* #var $Field MyType */
...
but it doesn't work.
Is there a way to achieve autocompletion of class fields with Eclipse and PDT?
thanks,
Silvio
And if you need it for a non-declared local variable you can use
/* #var $varname vartype */
This is very useful if you iterate over an array of objects with a foreach.
Please note that we need to type it with one asterisk /* and all in one line. Declaration should be placed before the use of the variable.
Yes there is!
Just simply put the var type before the declaration, like this :
/**
* #var Type
*/
protected $Field;
Make sure you use javadoc style comments (/** , not just /* )
I found this by selecting the field in the "Outline" view, and then right-click > Source > Generate element comment.