I have objects with many variables that I declare and explain in the comments. I am commenting very thoroughly for later processing using phpDoc, however I have no experience with actually compiling the documentation yet.
I find it very annoying that with phpDoc notation, each variable eats up four to six lines of code even if the only attribute I want to set is the description:
/**
* #desc this is the description
*/
var $variable = null;
I would like to use the following notation:
# #desc this is the description
var $variable = null;
is there a simple way to tweak phpDoc into accepting this, or will it give me trouble when I actually try to compile documentation out of it? I don't need the tweak now (although it's appreciated of course), just a statement from somebody who knows phpDoc whether this is feasible without having to re-engineer large parts of its code.
Just write one-line docblocks
/** #desc this is the description */
var $variable = null;
Problem solved.
In addition to what Frank Farmer mentioned (+1 to his solution),
/** is declared as T_DOC_COMMENT in the PHP tokenizer since PHP 5. This means to say that documentation notation are all parsed from /** to */.
You can't just use # or /* to write your PHP documentations.
See:
http://www.php.net/manual/en/tokens.php
Related
I'm on my way to upgrade my projects to PHP 8.0+. Until now, in the code comments, I used the #param and #return tags like in "option 1", instead of like in "option 2":
Option 1:
#param string[] ....
#return User[] ....
Option 2:
#param array ....
#return array ....
Though, because I don't know if the first form is officially allowed, I begin to ask myself, if it wouldn't be better to switch to the second option... So, I'd like to ask you: Is there any official PHPDoc reference for documenting PHP codes available?
Also, is it at all advisable to use the first option instead of the second one? In other words: are there any arguments speaking against it - having the future in mind too?
Thank you for your time.
P.S: I found the reference of PHPDocumentor, but I have the feeling, that it is not the official PHP one and not (yet) compatible with PHP 8.0+.
PHPDoc isn't a part of the official documentation but since it has been so widely adapted I highly doubt it will be ignored.
PHP itself prior to version 8 defines only comment syntax https://www.php.net/manual/en/language.basic-syntax.comments.php which does not include any # related elements.
Version 8 of PHP introduces attributes https://www.php.net/manual/en/language.attributes.overview.php which will be the native replacement for annotations.
For example https://api-platform.com/docs/core/filters/
PHP till 7.x
/**
* #ApiResource(attributes={"filters"={"offer.date_filter"}})
*/
class Offer
{
// ...
}
Since PHP 8
#[ApiResource(attributes: ['filters' => ['offer.date_filter']])]
class Offer
{
// ...
}
PSR Standard
PHP FIG defined 2 PSR standards ( Not approved yet )
PSR-5 https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc.md
PSR-19 https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc-tags.md
Though, because I don't know if the first form is officially allowed,
I begin to ask myself, if it wouldn't be better to switch to the
second option...
I will just stick with the Option 1. It is extremely beneficial for code completion standpoint.
an old fashioned example:
/**
* #param string $a - test parameter
*/
public function test($a)
{
}
but now that Php has types, I would write:
/**
* #param $a - test parameter
*/
public function test(string $a)
{
}
since it has a parameter, so adding "string" to phpdoc is verbose.
"Necessary" depends on what you're using to parse the annotation (if anything)*
If this is PHPDocumentor itself, you'll want to stick with the standard that it prescribes. Even if it works without the type now, there's no guarantee that a future version will, and as mentioned in Alex Howansky's answer, the type is currently defined as mandatory. From their manual:
With the #param tag it is possible to document the type and function of a single argument of a function or method. When provided it MUST contain a Type to indicate what is expected; the description on the other hand is OPTIONAL yet RECOMMENDED in case of complicated structures, such as associative arrays.
PHPStorm (at least the version I have in front of me) acts a bit strangely if you leave out the type-hint in a parameter. If I use
* #param $a Some useful comment about my parameter
then I get a warning about Undefined class Some. Apparently it's taking the first word other than the #param annotation and the variable name, and assuming that's the type. I can't find a reference to this behaviour in the phpdoc manual (providing the type after the variable), so that could itself be non-standard. Interestingly, if the first character after the variable name is a hyphen (as in the example in your question), then the warning is supressed.
I've seen a lot of code recently that leaves out the annotations entirely, and relies on the language's internal type-hinting (both parameter and return) to do the job. This is perfect, as long as you don't need to add a description to any of them. PHPStorm will warn you about missing parameter annotations the moment you provide any (but not all) of them, which means if you want to provide a comment for one then you'll need to add the rest, commented or not.
You mention verbosity in your question, and if all you're concerned about is human readability then by all means leave out the type. Phpdoc itself has a standard, but you're absolutely not bound by it. It's your code, ultimately. But if you're shipping a package that other developers might use, or if any of your toolchain (from IDE, through static analysis, to documentation generation itself) aren't happy with the non-standard usage, then you'll have to weigh up the decision again. Either way it comes down to whether you're the only one (person or machine) reading your code; if you're not, then stick with the standards, even if it means typing a few extra characters.
--
* This can include things that actually do affect the way the code runs - PHP allows you to fetch these annotations with the getDocComment methods in the Reflection API. Use-cases for this tend not to include #param annotations (more often it'll be something package specific like Doctrine's ORM annotations), which are almost exclusively used for documentation, but I don't want to over-generalise and say that this can't have an effect on your code's actual functionality.
The phpDocumentor docs state that the Datatype field is required for #param. Those docs are quite old, but I would expect apps which consume tags to still abide by that requirement. Lately, I've tended to skip the #param tag completely when I have an explicit typehint present.
PHPCS will alert if you leave it out but have a typehint, like in your example:
/**
* #param $arg The arg.
*/
public function foo(int $arg) {
PHPStan will alert if you have a #param tag type and a typehint that don't match, like this:
/**
* #param string $arg The arg.
*/
public function foo(int $arg) {
Wherever I go I see documentation for php with the following:
/*
* stuff
* stuff 2
*/
My question is can I get away with just:
/*
Stuff 1
Stuff 2
*/
Or is that for some reason counter indicated thanks?
Usually when you see coding habits following a particular pattern it is down to one of the following reasons:
Syntax denotes it
Coding style requests it
Programmatic parsing is enhanced by it.
With comments it is generally the latter two.
There are a number of coding styles for the /**/ comment block, across numerous languages (not just PHP). Coding styles generally are just personal/team preference, usually with some real arguments as to why a particular habit is preferred. Most often, readability is king.
The most common of these particular comment-styles would be what is referred to as a DocComment or DocBlock.
http://docs.phpdoc.org/guides/docblocks.html
This is a way of programatically powering the generation of your documentation directly from comments. Because the comments are parsed by code, it is specified with a particular pattern (note the /** prefix), making things easier to detect and reformat:
/**
* This is my DocBlock
*
* Each new line is prefix with a *
* and any special attributes are
* prefixed with an #something
*/
You by no means have to do this though, and a simple /* and */ will suffice for multiline comments. On the projects that I have worked on in the past, the difference between using a * on every line and not makes it clear when a comment is a real comment, against when it is just being used to comment out a portion of code.
The format you're describing is called PHPDoc. It's often used to document classes and methods (IDEs can make use of PHPDoc). This comment format is sometimes required to store annotations for various frameworks and libraries (e.g. Symfony uses it on controllers for routing.)
If you're not using annotations or documenting classes/functions, then there's no reason to write in the PHPDoc convention.
PHPDoc:
http://www.phptherightway.com/#phpdoc
Symfony annotation example (see the #Route examples):
https://symfony.com/doc/current/controller.html
Simply put, yes you can!
When creating .php files, the developer will often insert comments, as to add explanations for their coding.
There are two ways of adding comments. They are as follows:
/*[Comment Here]*/ This allows the Developer to add comments, which spread over multiple lines. For example:
/*
[This is a Comment]
[This is also a Comment]
*/
You just need to ensure that your Comment falls within the /**/ and that these are enclosed within the <?php [Code Data] ?> tags.
Alternatively, you can use '//'. Unlike the above, this will only allow you to insert a Comment on one line. If you were to go into the next line, you would need to add an additional //. Just like the above, you need to also ensure these // are placed within the <php? [Code Data] > tags.
As for the list of '*', I believe this is just for presentational and organisational purposes. They certainly do not affect the Comment itself.
PHP 5 can do some (limited) type hinting, however, it seems to me that in real-world projects, types are usually described in doc comments. For example, instead of this:
/**
* Test method
*/
function test(SomeType $param1) {
...
}
there will more commonly be
/**
* Test method
*
* #param SomeType param1
*/
function test($param1) {
...
}
What are the advantages and disadvantages of the two approaches? And if I'm right in the assumption that the PhpDoc method is more common, why is that? Why don't people utilize the built-in language feature more?
Edit: the third option is to use both approaches combined:
/**
* Test method
*
* #param SomeType param1
*/
function test(SomeType $param1) {
...
}
However, I personally haven't seen this used too often (looked at libraries like Symfony or PHPUnit) and this also seems like doing some work for not much additional benefit to be honest. Maybe that's why it isn't seen more often.
First thing: PHP typehints have different ability to hint than PHPDoc. Differences are (at least):
Scalar types. Before PHP 7.1, you can not hint scalar types, while nothing prevents you from hinting
/**
* #param string $param Param description
*/
Array of hinting. In PHPDoc you can hint, that parameter (or return value) is array of something. It would be:
/**
* #param ClassName[] $param Param description
*/
and meaning of this is - array of instances of ClassName. This is extremely useful when it comes to return type (because IDE then may do substitutions for methods on iteration of that array, and, therefore, you'll know that you're doing correct thing or not). However, in PHP you can only typehint it as
function functionName(array $param) { /*...*/ }
so it won't be possible to realize what are actual elements of array. For your information there is a corresponding RFC for typehinting as array of some elements, which is currently rejected - but may be in future such possibility will appear in PHP.
But, on the other hand, using PHP typehints is still different thing and normally you should do both - so, if it's possible to hint somehow in PHP (like for array sample above) - do it, and add PHPDoc block as well. PHP typehint allows you to enforce behavior on language level, while PHPDoc is only "information" source, it serves only information goal and can not prevent of passing illegal argument type.
Personally I would use both.
First option is good for controling what objects are you passing to the method. Second usually can be added automaticaly by any modern IDE and it makes your code more readable.
What does the #param mean when creating a class? As far as I understand it is used to tell the script what kind of datatype the variables are and what kind of value a function returns, is that right?
For example:
/**
* #param string $some
* #param array $some2
* #return void
*/
IsnĀ“t there another way to do that, I am thinking of things like: void function() { ... } or something like that. And for variables maybe (int)$test;
#param doesn't have special meaning in PHP, it's typically used within a comment to write up documentation. The example you've provided shows just that.
If you use a documentation tool, it will scour the code for #param, #summary, and other similar values (depending on the sophistication of the tool) to automatically generate well formatted documentation for the code.
As others have mentioned the #param you are referring to is part of a comment and not syntactically significant. It is simply there to provide hints to a documentation generator. You can find more information on the supported directives and syntax by looking at the PHPDoc project.
Speaking to the second part of your question... As far as I know, there is not a way to specify the return type in PHP. You also can't force the parameters to be of a specific primitive type (string, integer, etc).
You can, however, required that the parameters be either an array, an object, or a specific type of object as of PHP 5.1 or so.
function importArray(array $myArray)
{
}
PHP will throw an error if you try and call this method with anything besides an array.
class MyClass
{
}
function doStuff(MyClass $o)
{
}
If you attempt to call doStuff with an object of any type except MyClass, PHP will again throw an error.
I know this is old but just for reference, the answer to the second part of the question is now, PHP7.
// this function accepts and returns an int
function age(int $age): int{
return 18;
}
PHP is entirely oblivious to comments. It is used to describe the parameters the method takes only for making the code more readable and understandable.
Additionally, good code practice dedicates to use certain names (such as #param), for documentation generators.
Some IDEs will include the #param and other information in the tooltip when using a hovering over the relevant method.
#param is a part of the description comment that tells you what the input parameter type is. It has nothing to do with code syntax. Use a color supported editor like Notepad++ to easily see whats code and whats comments.