24

In PHP7, when a method sets a given parameter type and result type, is it necessary to document them again in the PHPDoc ?

Since

function foo(string $text): bool
{
    return true;
}

Is equivalent to

/**
 * @param string $text
 * @return bool
 */
function foo($text) {
    return true;
}

Is it necessary to duplicate these informations ?

/**
 * @param string $text
 * @return bool
 */
function foo(string $text): bool
{
    return true;
}

Edit : I don't use PHPDoc to generate my code's documentation, but to maintain a consistency in the methods for me and my coworkers with the help of PHPStorm.

Marc Brillault
  • 1,902
  • 4
  • 21
  • 41
  • Have you run phpdoc to see how it behaves when you declare parameter and result type? That will give you your answer. – John Conde Apr 30 '17 at 20:13
  • @JohnConde, isn't PHPDoc able to recognize this syntax ? – Marc Brillault Apr 30 '17 at 20:17
  • @MarcBrillault What he is trying to say is: **Try it and See** – Xatenev Apr 30 '17 at 20:40
  • 1
    PHPDoc is a documentator, i.e. giving description about functions, parameter aso. That IDEs use it to get information about the signature, is a nice side effect. "I don't use PHPDoc to generate my code's documentation" - so if you for some reason don't want it, just see what information your IDE does fetch. If you want to add something, just use PHPDoc comments as needed. imho no team developer should miss writing a documentation using PHPDoc. It is even helpful when developing allone. – Pinke Helga May 02 '17 at 16:47

2 Answers2

23

The docblock is something that a coder can use to explain what a function does, it will get ignored by the PHP parser (see Edit below), as it is just a comment it is a good practice to put a docblock above every function and method, because when someone (or you) read the code it is easier to see what the function does.

A IDE usually uses the docblock to for autocomplete, the docblock will however be overridden by the string and :bool when the block doesn't match the code

However

function foo(string $text): bool
{
    return true;
}

Is NOT equivalent to

/**
 * @param string $text
 * @return bool
 */
function foo($text) {
    return true;
}

The :bool in the first example enforces that foo() returns either true or false, anything else and PHP will try to cast the return to that type or throw a fatal error. It is the same with the typehint string for $text. The first parameter must be a value of type string, otherwise PHP tries to casts it to a string or a fatal error will be thrown

The @return bool and @param string enforces nothing at all, just says that the expected return is either true or false

Take the following example:

function foo(string $a) :bool
{
    var_dump($a); // string '10'
    return "string";
}

var_dump(foo(10)); // bool true

No problems there, PHP can cast 10 to a string and "string" is true There is a problem with the following though

function foo(PDO $a) :bool 
{
    var_dump($a);
    return "string";
}

var_dump(foo(10)); // fatal error, 10 is not PDO and can not be cast to PDO

Using the docblock will make the last one work(probably running into other problems further on because you are probably trying to do something with a PDO object)

Note: PHP does not yet have support for mixed type typehinting (ie string|array) that still has to be done by specifing it in a docblock

EDIT:
As @inwerpsel pointed out in the comments, my statement that a docblock is ignored by PHP parser is incorrect. A docblock can be read in during runtime by the ReflectionClass.

Shakir El Amrani
  • 331
  • 2
  • 16
Jelmergu
  • 973
  • 1
  • 7
  • 19
  • Thanks for the complete answer ! And also for mentioning the mixed type. – Marc Brillault May 18 '17 at 11:55
  • 2
    Thanks, was surprised to see that PHP would attempt to cast the types, though. Before writing this I thought that it would always throw a fatal error, then I went and tried my foo examples and was surprised by the results – Jelmergu May 18 '17 at 12:10
  • 2
    If you enforce type hint and return value checks with `declare(strict_types=1)` then you can rely on input argument to be really of type `string` and not `int` as in the previous example, and return value real `bool` instead of `string` as in the previous example. Simply put, use `declare(strict_types=1)` and you're safe. – ManInTheBox Jun 07 '17 at 10:15
  • 4
    "it is a good practice to put a docblock above every function and method" - totally disagree! First of all: Best practice would be writing functions that do one and only one thing. This would also make it easier for yourself to give this function a meaningful name. And if a function's name already tells me what it does, I don't need an additional comment. – codeFareith Jul 16 '18 at 10:51
  • 1
    Unfortunately, what you're suggesting is done by a lot of developers. And it's annoying! For example, if the function is called "getDataHandler", why put a docblock over it, in which it says "returns the data handler"? And if you ever find yourself in a situation where you have to explain your code, it might be better to think about refactoring. – codeFareith Jul 16 '18 at 10:51
  • 1
    "it will get ignored by the PHP parser, as it is just a comment" That is not true. The doc comment has its own parser token: T_DOC_COMMENT. It will be treated the same way as a regular T_COMMENT, with the exception that it can be accessed at runtime using the [ReflectionClass API](http://php.net/manual/en/reflectionclass.getdoccomment.php). – inwerpsel Jul 20 '18 at 12:54
-2

No, only add PHPDoc when you are actually documenting something, and don't repeat already typed hinted variables or specified return values. The recent version of PHP supports native-type hinting for the majority of PHPDoc directives.

Handsome Nerd
  • 17,114
  • 22
  • 95
  • 173