I've built quite an extensive web application and I was looking through the style guide for CodeIgniter (CI) to see how to do comments. It has things like this for classes and methods:
/**
* Super Class
*
* #package Package Name
* #subpackage Subpackage
* #category Category
* #author Author Name
* #link http://example.com
*/
class Super_class {}
/**
* Encodes string for use in XML
*
* #access public
* #param string
* #return string
*/
function xml_encode($str){}
This is fine but then I don't know what to fill out for these options. I don't really have #package, I just have some models and controllers. In Java I might use packages for security but not in CI, it's just the MVC. I always have things like, project_mode, projects (controller) and add_project_view.php for example.
Also what is the format for #category? The phpDocumentor docs say, "The #category tag is used to organize groups of packages together". Again, no packages!
Secondly, what about parameters in methods? Sometimes I have two strings and an array or an integer and an array, what is the format for #param?
Thanks,
Package, subpackage and category are for better structuring your code logically. It doesn't need to be there for every project/code file you have.
Params in methods on the other hand are very useful to be defined, because we need to know what they are when reading the documentation because we need to pass them while calling those methods in our code.
A sample would be like so:
/**
* Sample function
* #param string $param1 name of person
* #param integer $param2 age of person
* #return string
*/
function person($name, $age)
{
return "$name is $age years old";
}
#package can only be used to document procedural pages or classes.
Packages are used to help you logically group related elements. You
write classes to group related functions and data together, and
phpDocumentor represents the contents of files (functions, defines,
and includes) as "Procedural Pages." A package is used to group
classes and procedural pages together in the same manner that a
directory groups related files together.
You can find answers to your questions and more in phpDocumentor guide here
Related
I currently use such order of annotations:
Code 1:
/**
* sets elements for main (top), secondary (sub1) level and tertiary (sub2) level;
* prevents sharing of content with previous instances
*
* #param string $TopElement
* #param string $SubElement1
* #param string $SubElement2
*
* #return void
*
* #throws MarC_Exception if top element was not set
* #throws MarC_Exception if sub1 element was not set
* #throws MarC_Exception if sub2 element was not set
* #throws MarC_Exception if all elements were set the same
*/
public function __construct($TopElement="", $SubElement1="", $SubElement2="")
{
...
}
Code 2:
/**
* elements used for creation of code
*
* #static
* #var array
*/
protected $Elements = array();
Code 3:
/**
* #package ...
*
* #author ...
* #copyright ...
*
* #license ...
*
* generation of advanced select menu
*/
At this time i don't use all annotations (probably all I use you can see in codes above).
And I wonder if in php is any suggested (preffered) order of annotations - or it is free matter of programmer (and then this question will be useless).
TLDR; It's a free matter
PHP coding standards differ on this. The best I can suggest is to pick a coding standard you like and run PHP CodeSniffer (https://github.com/squizlabs/PHP_CodeSniffer) against it and see what it suggest. Some coding standards require they be in a specific order and a specific spacing to your docblock annotations. Others are more relaxed and make no suggestions about docblock annotations what-so-ever.
To get PHP Code Sniffer:
$ curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar
$ php phpcs.phar -h
$ php phpcs.phar --standard=[STANDARD_CHOICE] /path/to/project
Some coding standards you might want to consider:
http://www.php-fig.org/psr/psr-2/
http://framework.zend.com/manual/1.12/en/coding-standard.coding-style.html
http://pear.php.net/manual/en/rfc.header-comments.php
If you're worried about a document generators (like phpDocumentor) not being able to parse the docblock annotations, you can always check what annotations they support. I've never had a problem with phpDocumentor complaining about the ordering or formatting though.
As for custom annotations being used by libraries such as Doctrine, Symfony and PHPUnit, I've also never noticed the order having an impact on the parsing and processing.
I would love to post this as a general programming question. The reason I don't is that different documenting systems handle tags differently and therefore impose their own rules on what is "right" or "wrong" for a specific language.
Now the language in question is PHP. Which does not have a "standard" documentation system as of now. There is phpDocumentor, which while outdated as a project appears to have established the base. Current products like ApiGen seem to make an effort to support its syntax.
One tag I don't quite know where to put is the #author tag. I feel like placing it with the file level doc block. Together with #copyright, #license, #package and #link. Instead of inside the class level doc block. For some context: my PHP files contain one class declaration each only.
However, I failed to find the evidence supporting this to be an accepted standard. There is indeed little information to be found which location should be preferred. Which led me to believe that possibly I should include this information in both the file level doc block as well as the class level one.
Some examples:
OpenEMR appears to prefer using #author both inside the file level block as well as the class level one (http://www.open-emr.org/wiki/index.php/How_to_Document_Your_Code_Properly). The document does not specify whether that is intended to happen at the same time or only if the file does not contain a class but rather a number of functions:
/**
* library/sql_upgrade_fx.php Upgrading and patching functions of database.
*
* Functions to allow safe database modifications
* during upgrading and patches.
*
* Copyright (C) 2008-2012 Rod Roark <rod#sunsetsystems.com>
*
* LICENSE: This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>;.
*
* #package OpenEMR
* #author Rod Roark <rod#sunsetsystems.com>
* #author Brady Miller <brady#sparmy.com>
* #link http://www.open-emr.org
*/
/**
* inline tags demonstration
*
* This class generates bars using the main algorithm, which also
* works heavily with {#link foo()} to rule the world. If I want
* to use the characters "{#link" in a docblock, I just use "{#}link." If
* I want the characters "{#*}" I use "{#}*}"
*
* #author ahobbit
* #copyright middleearth.org XVII
* #version 1.2.3
*/
class bar
{
}
The two projects referenced by ApiGen however (Doctrine ORM API and Nette API) don't seem to use the #author tag in the file level doc block but exclusively with the class level doc block. But then the only examples I saw when browsing where those including class declarations.
Doctrine is using #author along with other tags, I would have thought placing in the file level doc block, inside the class level doc block (http://www.doctrine-project.org/api/orm/2.4/source-class-Doctrine.ORM.AbstractQuery.html#AbstractQuery):
/**
* Base contract for ORM queries. Base class for Query and NativeQuery.
*
* #license http://www.opensource.org/licenses/lgpl-license.php LGPL
* #link www.doctrine-project.org
* #since 2.0
* #version $Revision$
* #author Benjamin Eberlei <kontakt#beberlei.de>
* #author Guilherme Blanco <guilhermeblanco#hotmail.com>
* #author Jonathan Wage <jonwage#gmail.com>
* #author Roman Borschel <roman#code-factory.org>
* #author Konsta Vesterinen <kvesteri#cc.hut.fi>
*/
abstract class AbstractQuery
{ ... }
Nette, while also only using the #author tag in a class/interface context, does not appear to use #license #copyright or #link at all:
/**
* Translator adapter.
*
* #author David Grudl
*/
interface ITranslator
{...}
/**
* Component is the base class for all components.
*
* Components are objects implementing IComponent. They has parent component and own name.
*
* #author David Grudl
*
* #property-read string $name
* #property-read IContainer|NULL $parent
*/
abstract class Component extends Nette\Object implements IComponent
{...}
You can use it to document any element, so use it wherever it is appropriate and helpful for your needs.
From the manual:
Description
The #author tag is used to document the author of any element that can be documented (global variable, include, constant, function, define, class, variable, method, page). phpDocumentor will take any text between angle brackets
(< and >)
and try to parse it as an email address. If successful, it will be displayed with a mailto link in the page
NEW v1.2 - #author is now inherited by child classes from a parent class, see inline {#inheritdoc}.
Example
/**
* Page-Level DocBlock example.
* displays as Gregory Beaver<strong>cellog#php.net</strong>
* , where underlined text is a "mailto:cellog#php.net" link
* #author Gregory Beaver <cellog#php.net>
*/
/**
* function datafunction
* another contributor authored this function
* #author Joe Shmoe
*/
function datafunction()
{
...
}
Edit to clarify: Most times, a class is in a file by itself, so the file and class author are the same. So, you could have just one #author tag, in the file-level block. But not always: maybe the file was automatically generated by the project team as a placeholder, and a different author implemented it, or maybe there's some additional code in the file, like a one-time if statement to define some function if it doesn't already exist. In that case, the file and class may need different #author tags.
If you're concerned about clarity or find it helpful to have more detail, put it in both places; it can't hurt. Personally, if I'm adding #author tags, I'm going to add them to every file and pretty much every significant block of code. This approach makes sense if there's any chance a class will get turned into an interface or abstract class at some point down the road.
As an example, maybe you have a class DatabaseConnector, created by Joe, that hooks up to a MySQL database. As time goes on, you decide to make it more abstract so users can also use PostgreSQL. So, Bob turns DatabaseConnector into an abstract class, and Joe's original code becomes part of a new class, DatabaseConnectorMySQL. Joe is still the #author of DatabaseConnector.php and of all of the code in DatabaseConnectorMySQL, but Bob wrote all of the code currently in DatabaseConnector. So, both for giving credit where due and for telling people whom to contact if they have questions, you want to show who wrote what and who is responsible for certain choices (like method names).
Or, maybe you feel like that's just too much and adds confusion, and you'd rather just explain the history elsewhere in the docblock. Or maybe you don't care about #author tags at all, because all the info you need is stored in your version control repository (e.g., git blame). It's up to you; there is no wrong answer here.
I'm working on a project that uses the Lithium (http://li3.me/) framework and they document their classes like this:
class Controller extends \lithium\core\Object {
/**
* Contains an instance of the `Request` object with all the details of the HTTP request that
* was dispatched to the controller object. Any parameters captured in routing, such as
* controller or action name are accessible as properties of this object, i.e.
* `$this->request->controller` or `$this->request->action`.
*
* #see lithium\action\Request
* #var object
*/
public $request = null;
I've always used fully qualified class names in the #var and Eclipse seems to do a good job with that for generating content assist. However they seem to document class names using #see tags instead, and content assist is not available. Is there a way to configure PDT to use the information in the #see tag as a class name for the purposes of content assist?
It's not possible without own plugin. #see tag should be used for links only.
What is PHP Anotations and where can I learn more about it? I need simple example to understand it. I have googled around alot. Somehow i reached this point:
Example Code:
<?php
class AddressShipment{
/* Attributes of AddressShipment */
/**
* private TypePlaceShipment type
* #ORM\Id #ORM\Column #ORM\GeneratedValue
* #dummy
* #var long
*/
private $type;
/**
* private boolean lift
* #ORM\Column(type="boolean")
* #Assert\NotEmpty
* #var boolean
*/
private $lift;
/**
* private String comment
* #ORM\Column(type="string")
* #Assert\NotEmpty
* #var string
*/
private $comment;
?>
Can someone explain this a bit ? What are PHP Anotations? How can we use it ? What is the purpose of using it ?
It is basically for documentation generation.
Also IDEs which support php look up the annotations and give you information on what the function does, what it returns, what parameter it takes.
So if you make a php library, another person can read the annotations easily to know what it does without having to dig through your code and his IDE will recognize those annotations
here is an example of netbeans using this annotation from a function somewhere
You can learn by visiting this link:
http://manual.phpdoc.org/HTMLSmartyConverter/PHP/phpDocumentor/tutorial_elements.pkg.html
Aside from providing documentation (e.g. http://www.phpdoc.org/ ) and providing hints for the IDE, some libraries use annotations to determine how to handle classes. One example is Doctrine which provides an Object Relational Mapper that can map objects to a database based on annotations (using its database abstraction layer).
In the given code fragment I recognize #ORM\Id, #ORM\Column and #ORM\GeneratedValue as some of the annotations that Doctrine uses. However, AddressShipment is not declared as an Entity with the appropriate annotation, so they're not correctly used for that purpose.
Zend Framework 2 utilizes Doctrine's annotation library to enable the creation of forms from annotations (including validations and filtering).
Under the hood Doctrine uses reflection to read these annotations. If you use annotation-dependent libraries in combination with certain PHP accelerators, then you need to take care to configure the accelerator not to discard the annotations when it caches the code.
(Take note before reading that in fact I know you are talking about how to use some php ORM framework documentation tags and where to find what they mean).
Annotations are just annotations in PHP world they are called "PHPDoc Tags" but unfortunately they are used for nothing more than some PHP IDE code autocompletion / intellisense / documentation generation.
PHPDoc by itself is a standard that raised from nowhere but opensource php documentation project many years ago and was positively received from php community and now even php reflection class supports them.
For example phpdoc tag #return specifies what will be php class method return type or php function return type.
#var specifies what is property type. PHPDoc has its own declaration rules. For example documentation must begin with /** and must and with */. You can find this standards on http://en.wikipedia.org/wiki/PHPDoc#Tags link.
In example below all tags with # symbol are legal and might be treated by some PHP IDE like Netbeans or Eclipse or even Sublime sometimes. But:
class planet
{
/**
* primary
* length 16
* #var string
*/
public $name;
/**
* type smallint
* #var integer
*/
public $order;
/**
* #var boolean
*/
public $water;
/**
* #var \galaxy\star
*/
public $star;
/**
* enum
* #var \galaxy\moon
*/
public $moons = array ();
But what is interesting in your question is that you also mentioned #ORM. This means you are using some ORM framework probably Doctrine with Symphony and you need to find what does these annotations mean for specific framework. This can be found easily in specific framework's documentation. They are so many that there is no clue to post them on here.
For example if you are planning to use Doctrine you can visit here http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/getting-started.html
Or if you are using single file framework db.php which is database first style also and uses annotations as well you can visit here http://dbphp.net.
can someone explain or give some examples how to use the #Category Tag the right way ? PHPDocumentator is not parsing the Tag.
How does an correct File-DocBlock and Class-DocBlock looks like ?
I don't know if this helps, but... From the manual:
The #category tag is used to organize
groups of packages together. This is
directly applicable to the
XML:DocBook/peardoc2 Converter, and
can be used by other converters. Other
Converters packaged with phpDocumentor
ignore the category, but this may
change in future versions. It is also
possible to dynamically specify
category using the -dc,
--defaultcategoryname command-line switch.
/**
* Page-Level DocBlock
* #package MyPackage
* #category mycategory
*/
/**
* #global array used for stuff
*/
function mine()
{
global $baz;
...
}
Also, here's a sample of the proper way to write PEAR code, including DocBlocks with #category.
Please post some sample code that's not parsing -- that may help in answering what's wrong.
I haven't been able to find any useful examples on how to use the #category tag. It made sense to me to use it to represent the MVC layers using that tag ie:
/**
* Layout or template
*
* #category view
*/
/**
* Database representation of the user
*
* #category model
*/
/**
* Login actions
*
* #category controller
*/
That's how I use it.