PHP function comments - php

I've seen that some PHP functions are commented at the top, using a format that is unknown to me:
/**
*
* Convert an object to an array
*
* #param object $object The object to convert
* #return array
*
*/
My IDE gives me a dropdown selection for the things such as #param and #return, so it must be documented somewhere. I've tried searching google but it won't include the # symbol in its search.
What is this format of commenting and where can I find some information on it?

Functions:
/**
* Does something interesting
*
* #param Place $where Where something interesting takes place
* #param integer $repeat How many times something interesting should happen
*
* #throws Some_Exception_Class If something interesting cannot happen
* #author Monkey Coder <mcoder#facebook.com>
* #return Status
*/
Classes:
/**
* Short description for class
*
* Long description for class (if any)...
*
* #copyright 2006 Zend Technologies
* #license http://www.zend.com/license/3_0.txt PHP License 3.0
* #version Release: #package_version#
* #link http://dev.zend.com/package/PackageName
* #since Class available since Release 1.2.0
*/
Sample File:
<?php
/**
* Short description for file
*
* Long description for file (if any)...
*
* PHP version 5.6
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license#php.net so we can mail you a copy immediately.
*
* #category CategoryName
* #package PackageName
* #author Original Author <author#example.com>
* #author Another Author <another#example.com>
* #copyright 1997-2005 The PHP Group
* #license http://www.php.net/license/3_01.txt PHP License 3.01
* #version SVN: $Id$
* #link http://pear.php.net/package/PackageName
* #see NetOther, Net_Sample::Net_Sample()
* #since File available since Release 1.2.0
* #deprecated File deprecated in Release 2.0.0
*/
/**
* This is a "Docblock Comment," also known as a "docblock." The class'
* docblock, below, contains a complete description of how to write these.
*/
require_once 'PEAR.php';
// {{{ constants
/**
* Methods return this if they succeed
*/
define('NET_SAMPLE_OK', 1);
// }}}
// {{{ GLOBALS
/**
* The number of objects created
* #global int $GLOBALS['_NET_SAMPLE_Count']
*/
$GLOBALS['_NET_SAMPLE_Count'] = 0;
// }}}
// {{{ Net_Sample
/**
* An example of how to write code to PEAR's standards
*
* Docblock comments start with "/**" at the top. Notice how the "/"
* lines up with the normal indenting and the asterisks on subsequent rows
* are in line with the first asterisk. The last line of comment text
* should be immediately followed on the next line by the closing asterisk
* and slash and then the item you are commenting on should be on the next
* line below that. Don't add extra lines. Please put a blank line
* between paragraphs as well as between the end of the description and
* the start of the #tags. Wrap comments before 80 columns in order to
* ease readability for a wide variety of users.
*
* Docblocks can only be used for programming constructs which allow them
* (classes, properties, methods, defines, includes, globals). See the
* phpDocumentor documentation for more information.
* http://phpdoc.org/tutorial_phpDocumentor.howto.pkg.html
*
* The Javadoc Style Guide is an excellent resource for figuring out
* how to say what needs to be said in docblock comments. Much of what is
* written here is a summary of what is found there, though there are some
* cases where what's said here overrides what is said there.
* http://java.sun.com/j2se/javadoc/writingdoccomments/index.html#styleguide
*
* The first line of any docblock is the summary. Make them one short
* sentence, without a period at the end. Summaries for classes, properties
* and constants should omit the subject and simply state the object,
* because they are describing things rather than actions or behaviors.
*
* Below are the tags commonly used for classes. #category through #version
* are required. The remainder should only be used when necessary.
* Please use them in the order they appear here. phpDocumentor has
* several other tags available, feel free to use them.
*
* #category CategoryName
* #package PackageName
* #author Original Author <author#example.com>
* #author Another Author <another#example.com>
* #copyright 1997-2005 The PHP Group
* #license http://www.php.net/license/3_01.txt PHP License 3.01
* #version Release: #package_version#
* #link http://pear.php.net/package/PackageName
* #see NetOther, Net_Sample::Net_Sample()
* #since Class available since Release 1.2.0
* #deprecated Class deprecated in Release 2.0.0
*/
class Net_Sample
{
// {{{ properties
/**
* The status of foo's universe
* Potential values are 'good', 'fair', 'poor' and 'unknown'.
* #var string $foo
*/
public $foo = 'unknown';
/**
* The status of life
* Note that names of private properties or methods must be
* preceeded by an underscore.
* #var bool $_good
*/
private $_good = true;
// }}}
// {{{ setFoo()
/**
* Registers the status of foo's universe
*
* Summaries for methods should use 3rd person declarative rather
* than 2nd person imperative, beginning with a verb phrase.
*
* Summaries should add description beyond the method's name. The
* best method names are "self-documenting", meaning they tell you
* basically what the method does. If the summary merely repeats
* the method name in sentence form, it is not providing more
* information.
*
* Summary Examples:
* + Sets the label (preferred)
* + Set the label (avoid)
* + This method sets the label (avoid)
*
* Below are the tags commonly used for methods. A #param tag is
* required for each parameter the method has. The #return
* and #access tags are mandatory. The #throws tag is required if
* the method uses exceptions. #static is required if the method can
* be called statically. The remainder should only be used when
* necessary. Please use them in the order they appear here.
* phpDocumentor has several other tags available, feel free to use
* them.
*
* The #param tag contains the data type, then the parameter's
* name, followed by a description. By convention, the first noun in
* the description is the data type of the parameter. Articles like
* "a", "an", and "the" can precede the noun. The descriptions
* should start with a phrase. If further description is necessary,
* follow with sentences. Having two spaces between the name and the
* description aids readability.
*
* When writing a phrase, do not capitalize and do not end with a
* period:
* + the string to be tested
*
* When writing a phrase followed by a sentence, do not capitalize the
* phrase, but end it with a period to distinguish it from the start
* of the next sentence:
* + the string to be tested. Must use UTF-8 encoding.
*
* Return tags should contain the data type then a description of
* the data returned. The data type can be any of PHP's data types
* (int, float, bool, string, array, object, resource, mixed)
* and should contain the type primarily returned. For example, if
* a method returns an object when things work correctly but false
* when an error happens, say 'object' rather than 'mixed.' Use
* 'void' if nothing is returned.
*
* Here's an example of how to format examples:
* <code>
* require_once 'Net/Sample.php';
*
* $s = new Net_Sample();
* if (PEAR::isError($s)) {
* echo $s->getMessage() . "\n";
* }
* </code>
*
* Here is an example for non-php example or sample:
* <samp>
* pear install net_sample
* </samp>
*
* #param string $arg1 the string to quote
* #param int $arg2 an integer of how many problems happened.
* Indent to the description's starting point
* for long ones.
*
* #return int the integer of the set mode used. FALSE if foo
* foo could not be set.
* #throws exceptionclass [description]
*
* #access public
* #static
* #see Net_Sample::$foo, Net_Other::someMethod()
* #since Method available since Release 1.2.0
* #deprecated Method deprecated in Release 2.0.0
*/
function setFoo($arg1, $arg2 = 0)
{
/*
* This is a "Block Comment." The format is the same as
* Docblock Comments except there is only one asterisk at the
* top. phpDocumentor doesn't parse these.
*/
if ($arg1 == 'good' || $arg1 == 'fair') {
$this->foo = $arg1;
return 1;
} elseif ($arg1 == 'poor' && $arg2 > 1) {
$this->foo = 'poor';
return 2;
} else {
return false;
}
}
// }}}
}
// }}}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* c-hanging-comment-ender-p: nil
* End:
*/
?>
Source: PEAR Docblock Comment standards

That's PHPDoc syntax.
Read more here: phpDocumentor

You can get the comments of a particular method by using the ReflectionMethod class and calling ->getDocComment().
http://www.php.net/manual/en/reflectionclass.getdoccomment.php

You must check this: Docblock Comment standards
Sample File (including Docblock Comment standards)

Related

Reorder PHPDoc / Symfony annotations with csfixer

Is there a way with php-cs-fixer to define an order for Symfony annotations/PHPDoc ?
Here is two examples of a controller method and an entity property :
/**
* #Security()
*
* #ParamConverter()
*
* #Rest\Post()
* #Rest\View()
*
* #param Request $request
* #param xxxInterface $item
*
* #return \FOS\RestBundle\View\View
*/
public function myAction(Request $request, xxxInterface $item)
and
/**
* #var itemInterface
* #ORM\ManyToOne()
* #ORM\JoinColumn()
* #JMS\Groups()
* #JMS\AccessType()
* #MyCustomAssert\Assert1
*/
protected $item;
For methods, I want to set the order to #Security, #ParamConverter, #Rest then PHPDoc and for properties, I always want #MyCustomAssert at the end.
Is this something possible with php-cs-fixer ?
I think it isn't possible with php-cs-fixer (https://mlocati.github.io/php-cs-fixer-configurator/?version=2.9#version:2.15 might help searching)
However the slevomat coding standard for php code sniffer includes a sniff "SlevomatCodingStandard.Commenting.DocCommentSpacing" which allows you to configure annotationsGroups
The phpcbf script can reorder your annotations using this snif.

How to quickly contain pluralization failure in API Platform?

Built-in Symfony pluralization sometimes fails and API Platform relying on it builds the resource paths incorrectly (at least not the way I'd like them to be built).
For example: There's an English Dictionary API containing Entries and each Entry resource may have a PartOfSpeech subresource. In fact multiple PartS of Speech.
/**
* #ApiResource
* #ORM\Entity
*/
class Entry {
// ...
/**
* #var PartOfSpeech[]
*
* #ORM\OneToMany(targetEntity="PartOfSpeech", mappedBy="entry")
* #ApiSubresource
*/
public $partsOfSpeech;
}
/**
* #ApiResource
* #ORM\Entity
*/
class PartOfSpeech {
// ...
/**
* #var Entry
*
* #ORM\ManyToOne(targetEntity="Entry", inversedBy="partsOfSpeech")
*/
public $entry;
}
So, while I'd like the path to be parts_of_speech, API Platform will generate part_of_speeches or even parts_of_speeches (in case of the subresource) for the obvious reason. I know I can substitute paths operation by operation: collectionOperations={"get"={"path"="/parts_of_speech/{id}"}}. But I consider it a bit ugly and inconvenient. Is it possible to enforce a different path in a more elegant way? Preferably in one place per resource. And how to change a path of a subresource?
--
Clarification:
I can almost solve it as:
/**
* #ApiResource(
* collectionOperations={
* "get"={"path"="/parts_of_speech"},
* "post"={"path"="/parts_of_speech"},
* },
* itemOperations={
* "get"={"path"="/parts_of_speech/{id}"},
* "delete"={"path"="/parts_of_speech/{id}"},
* "put"={"path"="/parts_of_speech/{id}"},
* "patch"={"path"="/parts_of_speech/{id}"},
* },
* )
* #ORM\Entity
*/
class PartOfSpeech
{
It almost does the job but: 1. It's ugly so I ask if there is a shorter, more elegant solution; 2. Even if I write like this, I still don't know how to fix the plural in case of subresource. The following (a guess based on the documentation) doesn't work:
/**
* #ApiResource(
* subresourceOperations={
* "part_of_speech_get_subresource"={"path"="/entries/{id}/parts_of_speech"},
* }
* )
* #ORM\Entity
*/
class Entry
{
and still renders: /entries/{id}/parts_of_speeches
To do so you can use the routePrefix attribute:
/**
* #ApiResource(routePrefix="/parts_of_speech")
*/
class Entity
{
}

Would it make a difference to PHPdoc if I close my tags with colon (example)?

I always use colons in my phpdoc blocs. For example, instead of:
/** Some comment
*
*#private
*
*#param string $sTable The name of the table
*#return bool True otherwise void
*#example className->tableExists($sTable);
*#since date
*/
Instead of the above, I use the following style:
/** Some comment
*
* #private
*
* #param : string $sTable The name of the table
* #return : bool True otherwise void
* #example : className->tableExists($sTable);
* #since : date
*/
You see, I prefer to divide the tags and description with colons. It's easier to read and has more style. But I wonder if this makes any difference for PHPdoc parsing the docbloc at all?
To PHPDocumentor it makes quite a difference. Testing shows the following
/**
* Test constructor.
* #param : string $var testvar
*
*/
gets documented to:
Where
/**
* Test constructor.
* #param string $var testvar
*
*/
outputs
It is ofcourse somewhat logical that it is that way, as it is a syntax error. If you want to make the docblock look nice, you can align the values with spaces.
/** Some comment
*
*#private
*
*#param string $sTable The name of the table
*#return bool|void True otherwise void
*#example className->tableExists($sTable);
*#since date
*/
I'm not sure about PHPDoc itself, but it would make a difference to some IDEs. I tried this in PHPStorm and while #param and #var were unaffected, #return failed out.
I would be cautious using a non-standard format.

PhpDocs: Link to another method in "#deprecated" tag's description?

Is it possible to link to another method/class/property/etc. inside my project inline inside the #deprecated tag? Like this:
/**
* Method description
* #deprecated 1.0 Reason for deprecation, use {#link newMethod()} instead!
* #param string $str
* #param string|null $str2
* #return bool
*/
public function method($str, $str2) {
// TODO: Code...
}
...
?
According to PHPdoc.org, you could use the #see tag for that.
/**
* #see http://example.com/my/bar Documentation of Foo.
* #see MyClass::$items For the property whose items are counted.
* #see MyClass::setItems() To set the items for this collection.
*
* #return integer Indicates the number of items.
*/
function count()
{
<...>
}
Also, PHPdoc.org recommends to use #see in case of a #deprecated method:
It is RECOMMENDED (but not required) to provide an additional description stating why the associated element is deprecated. If it is superceded by another method it is RECOMMENDED to add a #see tag in the same PHPDoc pointing to the new element.
But #see is not always required, for example "Link to another method in #param tag's description?"

Tag #see in PhpStorm

I have the following code:
class A {
/**
* Splitter for words
*
* #var null|string
*/
private $splitter = '-';
/**
* Desc...
*
* #param null|string $splitter #see $splitter
*/
function __construct(
$splitter = null
) {
// implementation
}
}
$a = new A();
When using CTRL+Q in PhpStorm to see documentation for class constructor I will see:
null|string $splitter #see $splitter
Am I doing something wrong or should PhpStorm be configured to display description for $splitter here. I would expect here to have displayed Splitter for words or link to $splitter member and not just #see $splitter.
As I checked it doesn't matter that those 2 variables have the same name - even if constructor argument name would be $s PhpStorm still displays #see $splitter.
First of all: when in-lined (like you did) the PHPDoc tag should be surrounded by {}, like this: #param null|string $splitter {#see $splitter}
Secondly: PhpStorm does NOT parse additional/in-line tags in #param or #return descriptions -- it only parses it if #see is located on separate line or if in-lined in main (method) description section. In other words: in-lining in #param description will not work (very unfortunately).
In this regard PhpStorm behaves just like PhpDocumentor itself (checked using version 2.6.1).
Code:
<?php
class PHPDoc_See
{
/**
* Splitter for words
*
* #var null|string
*/
private $splitter = '-';
/**
* Desc... {#see $splitter}
*
* #param null|string $splitter Bla-Bla {#see $splitter}
*/
function __construct($splitter = null)
{
// implementation
}
}
PhpDocumentor result:
In this regard PhpStorm behaves a bit better -- at least it parses #see in main (method) description.
The only workable solution (as I see it) is to place #see tags on separate lines:
/**
* Some Description
*
* #param null|string $splitter Bla-Bla
* #see $splitter
*/
Of course: you can always submit Feature Request ticket to the PhpStorm's Issue Tracker (I would vote for it) .. but considering how PhpDocumentor is behaving in this regard .. I have serious doubts that PhpStorm devs will have it implemented any time soon (they do prefer following the same behaviour as referenced tool).

Categories